有没有一种方法可以将值分组并使用RxJava计算总和

时间:2019-05-22 17:36:18

标签: operators rx-java2 mathematical-optimization aggregation

我有一个Flowable对象列表。 示例-

values count
A      2
B      3
C      4
A      5
C      1

我希望根据值对流动资产进行分组,然后计算总和。有更好的方法吗?

我已经尝试生成多图。然后在订户中定义一个函数以汇总结果。但是,我觉得我没有有效地使用JavaRx在流中进行聚合。

 Flowable<Response> responseFlowable = Flowable.fromIterable(generateList());
        replayResponseFlowable.toMultimap(response -> response.getValues(), response -> response.getCount()).subscribe(groups-> calculateSum(groups));

    }

    private static void calculateSum(Map<String,Collection<Integer>> groups) 
   {
      //iterate over the map and calculate sum for each of the groups.  
   }        

预期结果是:

A      7
B      3
C      5

我希望使用JavaRx在流中进行此计算,而不是定义自定义方法。我该怎么办?

1 个答案:

答案 0 :(得分:1)

您可以将calculateSum放在流中,使其看起来更好。

replayResponseFlowable.toMultiMap(response -> response.getValues())
    .map(groups -> calculateSum(groups))
    .subscribe(result -> {
        print(result);
    })


由于您只是在汇总计数,因此您无需跟踪所有项目。相反,您只能保留每个值的计数总和。 可以使用.collect运算符来完成此操作:

replayResponseFlowable
    .collectInto(new HashMap<String, Integer>(), (group, response) -> {
         group.merge(response.values, response.count, Integer::sum);
    })
    .subscribe(result -> {
        print(result);
    });

这将打印

emitted=[{value=A, count=7}, {value=B, count=3}, {value=C, count=5}]


如果要获得可流动的发射物的结果,请使用.scan

    replayResponseFlowable
            .scan(new HashMap<String, Integer>(), (group, response) -> {
                group.merge(response.values, response.count, Integer::sum);
                return group;
            })
            .subscribe(result -> {
                print(result);
            });

这将打印:

emitted=[]
emitted=[{value=A, count=2}]
emitted=[{value=A, count=2}, {value=B, count=3}]
emitted=[{value=A, count=2}, {value=B, count=3}, {value=C, count=4}]
emitted=[{value=A, count=7}, {value=B, count=3}, {value=C, count=4}]
emitted=[{value=A, count=7}, {value=B, count=3}, {value=C, count=5}]