2017-05-02 4 views
1

私は "親"オブジェクトのリストを持っており、それぞれの "子"リストを取得したいと思います。結果として、親と子のリストが必要です。だから、結果はRxJava - リストとリクエストをマップに変換する

Map<Parent, List<Child>> result = new HashMap<>(); 

私のサンプル親リストである:

List<Parent> parents = new ArrayList<>(); 
parents.add(new Parent(1, "Parent1")); 
parents.add(new Parent(2, "Parent2")); 
parents.add(new Parent(3, "Parent3")); 
parents.add(new Parent(4, "Parent4")); 
parents.add(new Parent(5, "Parent5")); 

私はそれらを反復処理し、このための最良のRX構造は何である1

@GET("api/childs/{parentId}") 
Observable<Response<List<Child>>> getChilds(@Path("parentId") int parentId); 

で子どもたちにものをお願いしたいですか?両親を通じて

反復し、それぞれにflatMap()を使って子供たちとMap.Entryを形成しよう:

は、 ロバート

+0

「レスポンス」は誰ですか? –

+0

パッケージretrofit2; /** HTTP応答です。 */ public final classレスポンス { – Robertoq

答えて

2

私は考え、実装、これらの線に沿って、ありがとうございました。その後、それらを収集してMapにすることができます。コードは次のようになります。

public static void main(String[] args) { 

    List<Parent> parents = new ArrayList<>(); 
    parents.add(new Parent(1, "Parent1")); 
    parents.add(new Parent(2, "Parent2")); 
    parents.add(new Parent(3, "Parent3")); 
    parents.add(new Parent(4, "Parent4")); 
    parents.add(new Parent(5, "Parent5")); 

    Single<Map<Parent, List<Child>>> result = Observable.fromIterable(parents) 
      .flatMap(getMapEntries()) 
      .toMap(keySelector(), valueSelector()); 
} 

private static Function<Parent, Observable<Map.Entry<Parent, List<Child>>>> getMapEntries() { 
    return new Function<Parent, Observable<Map.Entry<Parent, List<Child>>>>() { 
     @Override 
     public Observable<Map.Entry<Parent, List<Child>>> apply(Parent parent) throws Exception { 
      return getChilds(parent.getId()) 
        .map(extractResponse()) 
        .map(createMapEntry(parent)); 
     } 
    }; 
} 

private static Function<Response<List<Child>>, List<Child>> extractResponse() { 
    return new Function<Response<List<Child>>, List<Child>>() { 

     @Override 
     public List<Child> apply(Response<List<Child>> listResponse) throws Exception { 
      return listResponse.body(); 
     } 
    }; 
} 

private static Function<List<Child>, Map.Entry<Parent, List<Child>>> createMapEntry(Parent parent) { 
    return new Function<List<Child>, Map.Entry<Parent, List<Child>>>() { 
     @Override 
     public Map.Entry<Parent, List<Child>> apply(List<Child> children) throws Exception { 
      return new AbstractMap.SimpleImmutableEntry<>(parent, children); 
     } 
    }; 
} 

private static Function<Map.Entry<Parent, List<Child>>, Parent> keySelector() { 
    return new Function<Map.Entry<Parent, List<Child>>, Parent>() { 
     @Override 
     public Parent apply(Map.Entry<Parent, List<Child>> parentListEntry) throws Exception { 
      return parentListEntry.getKey(); 
     } 
    }; 
} 

private static Function<Map.Entry<Parent, List<Child>>, List<Child>> valueSelector() { 
    return new Function<Map.Entry<Parent, List<Child>>, List<Child>>() { 
     @Override 
     public List<Child> apply(Map.Entry<Parent, List<Child>> parentListEntry) throws Exception { 
      return parentListEntry.getValue(); 
     } 
    }; 
} 

ただし、Responseのエラーも処理する必要があります。たとえば、例外をスローすることによってextractResponse()でそれを行うことができます。

Btw、childの複数形は、childrenである。 Pairは、2値leftrightの単純なラッパーである

0
Observable.from(parents) 
    .concatMap(p -> getChilds(p.getId()) 
     .map(Response::getValue) 
     .map(children -> Pair.of(p, children))) 
    .toMap(Pair::getLeft, Pair::getRight) 

関連する問題