组合相同类型的'n'可观察量(RxJava)

时间:2014-09-30 22:48:39

标签: java asynchronous reactive-programming observable rx-java

我有一个代码流,它生成一个相同类型的Iterable Observable。然后我仔细研究它们,将它们组合起来并将结果作为Observable返回。目前我正在使用带有FuncN的zip,这看起来很糟糕,我想我已经错过了某个地方。这是一个使用Map的例子,这显然是无稽之谈,但你明白了。

final ImmutableList.Builder<Map<String, Object>> observables = 
        ImmutableList.builder();
for (String key: keys) {
    if (someTest(key)) {
        observables.add(generateObservableMap(key));
    }
}

return Observable.zip(observables.build(), data -> {
    final Map<String, Object> result = Maps.newHashMap();

    // THIS IS REALLY UGLY
    for (Object d: data) {
        for (Object e: ((Map) d).entrySet()) {
            final Map.Entry entry = (Map.Entry) e;
            final String key = (Model) entry.getKey();
            final Object value = (AuthData) entry.getValue();
            result.put(key, value);
        }
    }

    return ImmutableMap.copyOf(result);
});

我确信有更好的方法可以做到这一点。

1 个答案:

答案 0 :(得分:0)

这实际上是关于Java Collections的问题,而不是关于RxJava的问题。您使用REALLY UGLY标记为putAll的部分可以更好一些:

@SuppressWarnings("unchecked")
public static <K, V> Map<K, V> mergeMaps(Object... maps) {
    final Map<K, V> result = new HashMap<K, V>();
    for (Object map: maps) {
        // unchecked <K,V> require @SuppressWarnings
        result.putAll((Map<K,V>)map);
    }
    return result;
}

请注意,如果在多个地图中出现相同的密钥,则只有最后一个值才会出现在结果中。

您可能想知道为什么我选择Object...作为参数类型而不是Map<K,V>...。原因是FuncN将有一个Object[],无法转换为Map<K,V>[],因为这会抛出ClassCastException,即使数组中的所有元素都是输入Map

现在,如果您在sampleObservables中有Iterable<Observable<Map<String, Object>>>,则可以使用zipmergeMaps,如下所示:

return Observable.zip(sampleObservables, new FuncN<Map<String, Object>>() {
    public Map<String, Object> call(Object... args) {
        return mergeMaps(args);
    }
});