Java 根据Id组合接收流

Java 根据Id组合接收流,java,observable,rx-java,Java,Observable,Rx Java,我有两个发射对象的流,一个类型为A,另一个类型为B。它们都包含一个字段,我们称之为id Observable<A> observableA = // by calling service A Observable<B> observableB = // by calling service B 从observableA和observableB发射对象的顺序可能不同。例如,observableA可以首先发射id为1的对象,但observableB可能会发射id为2的对象

我有两个发射对象的流,一个类型为
A
,另一个类型为
B
。它们都包含一个字段,我们称之为
id

Observable<A> observableA = // by calling service A
Observable<B> observableB = // by calling service B
从observableA和observableB发射对象的顺序可能不同。例如,observableA可以首先发射id为1的对象,但observableB可能会发射id为2的对象

我发现的一种方法是将put元素保持在两个不同的映射(MapA和MapB)中,因为它们是发射的,而当两个映射中都存在值时,它们将发射
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
 })
Map mapA=newhashmap();
Map mapB=新的HashMap();
Observable Observable EC=Observable.merge(Observable EA,Observable EB).map(obj->{
if(A的obj实例){
if(mapB.containsKey(((A)obj.getId()){
//创建对象C
}否则{
mapA.put(((A)obj.getId());
}
}
if(B的obj实例){
//与上述检查相同
})
我想知道是否有更干净的方法来实现这一点(可能使用一些rx java操作符)。

您可以使用操作符来实现这一点:

Observable.merge(s1,s2)
.groupBy(obj->obj.getId())
.flatMapSingle(grp->grp.toList()
.map(l->/*在此处创建对象C*/)
)
.subscribe();
groupBy
将源
Observable
实例分解为单独的
GroupedObservable
实例,每组一个实例,由传递给
groupBy
的键选择器函数返回的值决定。在这种情况下,对于每个唯一ID,您将得到一个
GroupedObservable
通过对
getId
的所有调用打开。从那里,我们将共享一个ID的所有对象合并到一个列表中。此时,您可以自由使用所有这些对象来创建
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
 })