使用RxJava

时间:2016-04-14 19:18:04

标签: rx-java

我试图实现某种流解析器。让我们说我有整数流,我将它们组合起来创建新对象,它聚合了部分流。

例如,对象是"完成"当整数为负数时。为了简单起见,生产的项目将是数字串。

这是一个简单的例子:

Source: 1, -2, 3, 4, -5, 6, -7, 8, 9, 10, -11
Output: "1-2", "343-5", "6-7", "8910-11"

我无法找到现有运营商的正确组合。我的解决方案是提供自定义运算符,将数据聚合到" chunk"有效并发出新对象:

rx.Observable<Integer> src = rx.Observable
    .from(Arrays.asList(1, -2, 3, 4, -5, 6, -7, 8, 9, 10, -11));

rx.Observable<String> res = src
    .lift(new rx.Observable.Operator<String, Integer> () {

        @Override
        public rx.Subscriber<? super Integer> call(
            final rx.Subscriber<? super String> subscriber) {

            return new rx.Subscriber<Integer>(subscriber) {

                private final StringBuilder cur = new StringBuilder();

                @Override
                public void onCompleted() {
                    if (!subscriber.isUnsubscribed()) {
                        subscriber.onCompleted();
                    }
                }

                @Override
                public void onError(Throwable e) {
                    if (!subscriber.isUnsubscribed()) {
                        subscriber.onError(e);
                    }
                }

                @Override
                public void onNext(Integer i) {
                    if (subscriber.isUnsubscribed())
                        return;

                    cur.append(i).append('');
                    if (i < 0) {
                        subscriber.onNext(cur.toString());
                        cur.delete(0, cur.length());
                    }
                }
            };
        }
    });

rx.observers.TestSubscriber<String> sub =
    new rx.observers.TestSubscriber<>();
res.subscribe(sub);
List<String> l1 = sub.getOnNextEvents();

直到我在它们上面使用一些位置运算符,例如 take(N) combineLatest ,它才能正常工作。

rx.Observable<String> res2 = res.take(2);

在这种情况下,我没有 onCompleted onError ,并且会发出少量的项目。

看起来每个输入 onNext 都应该输出 onNext

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

嗯。写长篇文章确实有助于提出新想法并且它有效。 (我已经开了2天了。)

生成Observer<Observer<String>>并发出Observer.empty()直到对象准备就绪。 flatMap之后。

以下是工作示例:

rx.Observable<rx.Observable<String>> res = src
    .lift(new rx.Observable.Operator<rx.Observable<String>, Integer> () {

        @Override
        public rx.Subscriber<? super Integer> call(
            final rx.Subscriber<? super rx.Observable<String>> subscriber) {

            return new rx.Subscriber<Integer>(subscriber) {

                private final StringBuilder cur = new StringBuilder();

                // onError, onCompleted skipped

                @Override
                public void onNext(Integer i) {
                    rx.Observable<String> out;
                    cur.append(i);
                    if (i < 0) {
                        out = rx.Observable.just(cur.toString());
                        cur.delete(0, cur.length());
                    } else {
                        out = rx.Observable.<String>empty();
                    }
                    subscriber.onNext(out);
                }
            };
        }
    });

rx.Observable<String> res2 = res
    .flatMap(stringObservable -> stringObservable)
    .take(2);