使用RxJava进行分组移动平均值

时间:2019-11-05 08:16:37

标签: java rx-java2

我可以很容易地计算出一个简单整数列表的移动平均值,例如:

Integer arr[] = {1, 2, 3, 4, 5, 6};                        
Observable<Integer> oi = Observable.from(arr);                          
oi.buffer(24, 1).subscribe(x -> average(x))

现在可以说我有对象,而不是像这样的整数

private class Model{
  public String key;
  public Double value;
}

我想以{strong>非阻塞的方式(例如,我从rabbitmq获取连续流)基于key分组并计算移动平均值,该方式将发出{ {1}}个值。

我知道{key->average}运算符,但是使用它时会变得混乱。用groupBy做到这一点的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

您可以这样做:

Observable<Model> oi = ...;
oi.groupBy(model -> model.key)
    .flatMapSingle(Observable::toList)
    .subscribe(modelsGrouped -> { // key: modelsGrouped.get(0).key
        double avg = average(modelsGrouped);
        //...
    });

希望有帮助!

答案 1 :(得分:1)

我对问题的理解是,存在无限个流,目标是计算该流上滑动窗口的平均值。但是问题尚不清楚,有几种不同的解释方式。

CASE 1. The sliding window is the most recent 24 items of the stream.
CASE 2. The sliding window is the most recent 24 items per type.
    CASE 2.1 Each emit is the average of the most recent sliding window that has moved.
    CASE 2.2 Each emit should contain averages of all groups.
    CASE 2.3 Or some other forms..

如果您可以提供示例输入和预期输出,将会很有帮助。

以下答案适用于CASE 2.1:

oi.groupBy(model -> model.key) // [1]
        .flatMap(groupedO -> groupedO.buffer(4, 1) // [2]
                .map(list -> {
                    double avg = list.stream().mapToDouble(m -> m.value)
                            .average().orElse(0.0);
                    return new Model(list.get(0).key, avg); // [3]
                }))
        .subscribe(result -> { //[4]
            // do something
        });
  1. 基于密钥分组
  2. buffer应用于可观察的分组
  3. 计算平均值
  4. 结果采用Model(group, average)
  5. 的形式