将2个RxJava Observable转换为1个Map

时间:2016-07-05 11:36:30

标签: java dictionary stream rx-java

我有以下情况。我使用Retrofit2从服务器获取数据。 我想下载Directory.GetFilesCollection<Account>个实体,并为每个帐户下载AccountCollection<Project>个实体。最后我想得到Project

我有以下方法:

  1. Map<Account, Collection<Project>> accountsWithProjects
  2. Observable<Collection<Account>> requestAllAccounts()
  3. 问题:是否可以压缩或创建这两个反应流的迭代,并将所有项目收集到地图中?

    如果它有帮助,我也可以同步获取帐户项目的集合,但是无法在主线程上进行,因为开发Android并且必须在主线程上观察结果。

2 个答案:

答案 0 :(得分:1)

你有它:

requestAllAccounts().flatMap(new Func1<Collection<Account>, Observable<Account>>() {
        @Override
        public Observable<Account> call(Collection<Account> accountCollection) {
            return Observable.from(accountCollection);
        }
    }).flatMap(new Func1<Account, Observable<Pair<Account, Collection<Project>>>>() {
        @Override
        public Observable<Pair<Account, Collection<Project>>> call(Account account) {
            return Observable.just(account).zipWith(requestProjectsInfoForTempoAccount(account),
                    new Func2<Account, Collection<Project>, Pair<Account, Collection<Project>>>() {
                        @Override
                        public Pair<Account, Collection<Project>> call(Account account, Collection<Project> projects) {
                            return new Pair<Account, Collection<Project>>(account, projects);
                        }
                    });
        }
    }).toList()
            .flatMap(new Func1<List<Pair<Account, Collection<Project>>>, Observable<Map<Account, Collection<Project>>>>() {
                @Override
                public Observable<Map<Account, Collection<Project>>> call(List<Pair<Account, Collection<Project>>> pairs) {
                    Map<Account, Collection<Project>> map = new HashMap<Account, Collection<Project>>();
                    for (Pair<Account, Collection<Project>> pair : pairs) {
                        map.put(pair.first, pair.second);
                    }
                    return Observable.just(map);
                }
            });

这里发生了什么?

  1. 获取所有帐户。
  2. 将列表拆分为单个帐户
  3. 调用单个帐户上的项目搜索并返回Pair<Account, Collection<Project>>
  4. 合并所有对象
  5. List<Pair<Account, Collection<Project>>>转换为Map<Account, Collection<Project>>

答案 1 :(得分:1)

这是一个更好的方法:

requestAllAccounts()
.flatMap(account -> requestProjectsInfoForTempoAccount(account),
   (acccount, projects) -> Pair::of)
.toMap(Pair::key, Pair::value);

(扩展到Java 7作为读者的练习)