根据ID合并Rx流

时间:2020-06-22 11:04:44

标签: java observable rx-java

我有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运算符)。

1 个答案:

答案 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的实例。