web-dev-qa-db-ja.com

連結VSマージ演算子

RXJavaのドキュメントを確認していたところ、連結演算子とマージ演算子が同じように見えることに気付きました。念のため、いくつかのテストを作成しました。

@Test
public void testContact() {

    Observable.concat(Observable.just("Hello"),
                      Observable.just("reactive"),
                      Observable.just("world"))
              .subscribe(System.out::println);
}

@Test
public void testMerge() {

    Observable.merge(Observable.just("Hello"),
                      Observable.just("reactive"),
                      Observable.just("world"))
            .subscribe(System.out::println);
}

ドキュメントには

マージ演算子も同様です。 Concatは複数のObservableの放出を組み合わせますが、それらをインターリーブする場合がありますが、Concatは複数のObservableからの放出をインターリーブしません。

しかし、このテストを何千回実行しても、マージ結果は常に同じです。注文が許可されていないので、たとえば「リアクティブ」、「ワールド」、「ハロー」などを期待していました。

コードはこちら https://github.com/politrons/reactive

40
paul

引用したドキュメントに記載されているとおりです-マージは出力をインターリーブできますが、concatは最初に以前のストリームが終了するのを待ってから後のストリームを処理します。あなたの場合、単一要素の静的ストリームでは、実際の違いはありません(ただし、理論的には、マージはランダムな順序で単語を出力し、依然として仕様に従って有効です)。違いを確認したい場合は、次のことを試してください(早期終了を避けるために、後でスリープを追加する必要があります)

    Observable.merge(
            Observable.interval(1, TimeUnit.SECONDS).map(id -> "A" + id),
            Observable.interval(1, TimeUnit.SECONDS).map(id -> "B" + id))
    .subscribe(System.out::println);

A0 B0 A1 B1 B2 A2 B3 A3 B4 A4

versus

    Observable.concat(
            Observable.interval(1, TimeUnit.SECONDS).map(id -> "A" + id),
            Observable.interval(1, TimeUnit.SECONDS).map(id -> "B" + id))
    .subscribe(System.out::println);

A0 A1 A2 A3 A4 A5 A6 A7 A8

ストリームAが終了しないため、ConcatはBの印刷を開始しません。

s/stream/observable/g;)

ドキュメンテーションは、違いを示す素敵なグラフを提供します。マージは、アイテムを1つずつインターリーブする保証を与えないことを覚えておく必要があります。これは単なる例の1つです。

Concat

Concat operatorマージ

Merge operator

125

連結

Concatは、2つ以上のObservableからの放出をインターリーブせずに放出します。アイテムを放出している間、オブザーバブルの順序を維持します。これは、最初のオブザーバブルのすべてのアイテムを放出し、次に2番目のオブザーバブルのすべてのアイテムを放出することを意味します。

Concat Operator

例で明確に理解しましょう。

final String[] listFirst = {"A1", "A2", "A3", "A4"};
final String[] listSecond = {"B1", "B2", "B3"};

final Observable<String> observableFirst = Observable.fromArray(listFirst);
final Observable<String> observableSecond = Observable.fromArray(listSecond);

Observable.concat(observableFirst, observableSecond)
        .subscribe(new Observer<String>() {

            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(String value) {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });

連結演算子を使用しているため、順序を維持し、値をA1、A2、A3、A4、B1、B2、B3として出力します。

マージ

Mergeは、複数のObservableを、それらの放出をマージすることにより1つに結合します。アイテムを発行している間は順序を維持しません。

Merge Operator

例で明確に理解しましょう。

final String[] listFirst = {"A1", "A2", "A3", "A4"};
final String[] listSecond = {"B1", "B2", "B3"};

final Observable<String> observableFirst = Observable.fromArray(listFirst);
final Observable<String> observableSecond = Observable.fromArray(listSecond);

Observable.merge(observableFirst, observableSecond)
        .subscribe(new Observer<String>() {

            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(String value) {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });

Merge Operatorを使用しているため、順序は維持されず、A1、B1、A2、A3、B2、B3、A4またはA1、A2、B1、B2、A3、A4、B3または何でもかまいません。

これは、ユースケースに応じて、RxJavaでConcatおよびMerge演算子を使用する方法です。

2
Amit Shekhar