我有2个流发出对象,其中一个流类型为A
,另一个流类型为B
。它们都包含我们称为id
的字段。
Observable<A> observableA = // by calling service A
Observable<B> observableB = // by calling service B
我想将这两个流合并为一个对象C
的单个流,其中将包含来自两个对象的数据。
Observable<C> observableC = //Some fuction to merge observableA and observableB
从observableA和observableB发出对象的顺序可以不同。例如,observableA可以首先发出ID为1的对象,但是observableB可能会发出ID为2的对象。
我发现执行此操作的一种方法是将元素放置在2个不同的Map(MapA和MapB)中,并在两个Map中都存在值时发出它们,并发出C
。
Map<String,A> mapA = new HashMap<>();
Map<String,B> mapB = new HashMap<>();
Observable<C> observableC = Observable.merge(observableA,observableB).map(obj->{
if(obj instanceof A) {
if(mapB.containsKey(((A)obj).getId()){
//create object C
} else {
mapA.put(((A)obj).getId());
}
}
if(obj instanceof B){
// same checks as above
})
我想知道是否有更清洁的方法(可能使用一些rx java运算符)。
答案 0 :(得分:1)
您可以为此使用groupBy
运算符:
Observable.merge(s1, s2)
.groupBy(obj -> obj.getId())
.flatMapSingle(grp -> grp.toList()
.map(l -> /* create object C here */)
)
.subscribe();
groupBy
会将您的源Observable
实例分解为单独的GroupedObservable
实例,每组一个实例,具体取决于您传递给{{的键选择器函数返回的值1}}。在这种情况下,您对groupBy
的所有调用返回的每个唯一ID将获得一个GroupedObservable
。从那里,我们将共享ID的所有对象组合到一个列表中。届时,您可以随意使用所有这些对象来创建getId
的实例。