rxjava从缓冲区中检索最大值

时间:2016-11-07 12:04:34

标签: max buffer rx-java reactive-programming

我正在使用rxjava 1.2.2。

从我的列表开始我想填充一个缓冲区然后过滤缓冲区的Max项,例如,每隔5秒只需要发出Max Item过滤器。

Observable<Item> EventEmitter =  Observable.from(itemsList);

Observable<List<Item>> tapBufferEmitter = tapEventEmitter.buffer(5, TimeUnit.SECONDS);

MathObservable.from(tapBufferEmitter).max(new Comparator<List<Item>>()  {

            @Override
            public int compare(List<Item> o1, List<Item> o2) {
                int m1 =o1.getVal();
                int m2 = o1.getVal();
                if (m1 == m2){
                    return 0;
                } else if (m1 > m2){
                    return 1;
                } else {
                    return -1;
                }                           
            }
        }).subscribeOn(Schedulers.from(executor1))
        .subscribe(s -> {
            System.out.println("Called thread: " +  Thread.currentThread().getId());

            syso.("Max Item is:" + s.getId());
        }, e -> System.out.println(e.getMessage()));

但当然上面的代码片段无效。我不想比较2列表o1和o2,但我想比较同一列表中的项目。

max运算符是正确的选择吗?请注意,我不是比较整数而是比较项目。每个项目都是一个固定字段的珠子。我想要一个具有该字段最大值的那个。

如何从缓冲区中选择最大值? 感谢

2 个答案:

答案 0 :(得分:1)

我写了一个例子,如何使用MathObservable.max运算符。请注意,我确实使用了窗口而不是缓冲区,因为缓冲区将返回一个List,窗口将为我提供一个Observable,我可以将其与flatMap和MathObservablen一起使用。然后MathObservable将计算给定窗口的最大值(可观察到5个元素)。

摇篮:

compile 'io.reactivex:rxjava:1.2.1'
compile 'io.reactivex:rxjava-math:1.0.0'

窗口:

@Test
public void windowMaxTest() throws Exception {
    Observable<Integer> just = Observable.just(10, 9, 8, 4, 7, 5, 6, 8, 4, 3);

    Observable<Integer> integerObservable1 = just.window(5)
            .flatMap(integerObservable -> {
                return MathObservable.max(integerObservable);
            });

    TestSubscriber<Integer> testSubscriber = new TestSubscriber<>();

    integerObservable1.subscribe(testSubscriber);

    testSubscriber.awaitTerminalEvent();
    testSubscriber.assertValues(10, 8);
}

缓冲液:

@Test
public void bufferMaxTest() throws Exception {
    Observable<Integer> just = Observable.just(10, 9, 8, 4, 7, 5, 6, 8, 4, 3);

    Observable<Integer> integerObservable1 = just.buffer(5)
            .flatMap(integerObservable -> {
                return MathObservable.max(Observable.from(integerObservable));
            });

    TestSubscriber<Integer> testSubscriber = new TestSubscriber<>();

    integerObservable1.subscribe(testSubscriber);

    testSubscriber.awaitTerminalEvent();
    testSubscriber.assertValues(10, 8);
}

自定义对象::

class Item {
    public int value;

    public Item(int value) {
        this.value = value;
    }
}

@Test
public void test3214() throws Exception {
    final Item max1 = new Item(3);
    final Item max2 = new Item(6);
    final List<Item> myListOfItem = Arrays.asList(new Item(1), new Item(2), max1, new Item(4), new Item(5), max2);

    Observable<Item> itemObservable1 = Observable
            .from(myListOfItem)
            .buffer(3)
            .flatMap(itemObservable -> {
                Observable<Item> from = Observable.from(itemObservable);

                return MathObservable.from(from)
                        .max((item, t1) -> {
                            return Integer.compare(item.value, t1.value);
                        });
            });

    TestSubscriber<Item> testSubscriber = new TestSubscriber<>();

    itemObservable1.subscribe(testSubscriber);

    testSubscriber.awaitTerminalEvent();

    testSubscriber.assertValues(max1, max2);
}

答案 1 :(得分:0)

一般来说, .reduce()是获取min / max / avg / sum等的标准选择。

reduce(0, /*return Math.max(lhs, rhs)*/)

所以整个操作都是这样的 -

source.window(/*...*/).flatMap(/*return .reduce(0, /*return Math.max(lhs, rhs)*/))