我有一个代码流,它生成一个相同类型的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);
});
我确信有更好的方法可以做到这一点。
答案 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>>>
,则可以使用zip
和mergeMaps
,如下所示:
return Observable.zip(sampleObservables, new FuncN<Map<String, Object>>() {
public Map<String, Object> call(Object... args) {
return mergeMaps(args);
}
});