RxJava - 将列表和请求转换为地图

时间:2017-05-02 10:59:02

标签: java android rx-java rx-java2

我有一个" Parent"对象,我想得到一个"孩子"每个人的清单。我想要一个父子列表的地图。结果是

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"));

我想迭代他们并逐个问孩子

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

最好的RX结构是什么?

谢谢你, 罗伯特

1 个答案:

答案 0 :(得分:2)

我想到的实现是这样的:

通过父母进行迭代,并尝试使用Map.Entry与孩子一起形成flatMap()。然后,您可以将它们收集到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()中执行此操作,例如抛出异常。

顺便说一下,child的复数是children