web-dev-qa-db-ja.com

RxJavaのconcatMapとflatMapの違いは何ですか

これらの2つの関数はかなり似ているようです。署名は同じです(rx.functions.Func1<? super T, ? extends Observable<? extends R>> func)、およびそれらの大理石図はまったく同じに見えます。ここに写真を貼り付けることはできませんが、これは concatMap の場合と flatMap の場合です。結果のObservableの記述には微妙な違いがあるようです。concatMapによって生成されたものには、結果のObservableを連結した結果のアイテムが含まれ、flatMapによって生成されたものには、結果のObservablesを最初にマージし、その合併。

しかし、この微妙さは私にはまったくわかりません。誰でもこの違いのより良い説明を与えることができ、理想的にはこの違いを示すいくつかの例を与えることができます。

41
Haspemulator


あなたが書いたように、2つの関数は非常に似ており、微妙な違いは出力の作成方法です(マッピング関数が適用された後)。

フラットマップでは マージ演算子 を使用しますが、concatMapでは concat演算子 を使用します。

ConcatMapの出力シーケンスが順序付けられているのを確認します。最初のObservableによって発行されたすべてのアイテムは、2番目のObservableによって発行されたアイテムよりも前に発行されます。
flatMapの出力シーケンスがマージされている間-マージされたObservableによって発行されたアイテムは、どのソースObservableに由来するかに関係なく、任意の順序で表示されます。

55

1つの非常に重要な違い:concatMapは、現在の発行されたobservableが完了するまで待機し、flatMapは完了しません。 flatMapはできるだけ多くの起動を試みます。簡単に言うと、無限のものを連結することはできません。 concatMapで出力するオブザーバブルが完了できることを確認してください.

14
WindRider

ここでの答えは良いものの、例がなければ違いを見つけるのは簡単ではありませんでした。そこで、このための簡単な例を作成しました。

@Test
public void flatMapVsConcatMap() throws Exception {
    System.out.println("******** Using flatMap() *********");
    Observable.range(1, 15)
            .flatMap(item -> Observable.just(item).delay(1, TimeUnit.MILLISECONDS))
            .subscribe(x -> System.out.print(x + " "));

    Thread.sleep(100);

    System.out.println("\n******** Using concatMap() *********");
    Observable.range(1, 15)
            .concatMap(item -> Observable.just(item).delay(1, TimeUnit.MILLISECONDS))
            .subscribe(x -> System.out.print(x + " "));

    Thread.sleep(100);
}

******** flatMap()を使用***********

1 2 3 4 5 6 7 9 8 11 13 15 10 12 14

******** concatMap()の使用***********

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

出力からわかるように、flatMapの結果は順不同ですが、concatMapの結果は順不同です。

14
Anatolii