RxJavaのフラットマップとスイッチマップの違い

RxJavaのFlatmapとSwitchmapの違い

1. 概要

RxJavaは、オブザーバブルによって放出されるアイテムを他のオブザーバブルに変換するためのさまざまな演算子を提供します。 最も人気のある演算子の2つは、flatMapswitchMapです。 リアクティブプログラミングの初心者にとって、この2つの違いを理解するのは難しい場合がよくあります。

RxJavaの概要については、this articleを参照してください。

このチュートリアルでは、簡単な例を見て、違いを理解します。

2. flatMap

The flatMap operator converts each item returned from a source observable into an independent observable using the supplied function and then merges all the observables into a single observable。 オブザーバブルがマージされる順序は、ソースObservable.と同じであるとは限りません。

例として検索エンジンを取り上げましょう。 単語の各文字を入力した直後に検索結果を表示するとします。

簡単にするために、検索クエリの入力を単語のリストとして使用しました。

また、各単語に対して常に2つの検索結果を返します。

// given
List actualOutput = new ArrayList<>();
TestScheduler scheduler = new TestScheduler();
List keywordToSearch = Arrays.asList("b", "bo", "boo", "book", "books");

// when
Observable.fromIterable(keywordToSearch)
  .flatMap(s -> Observable.just(s + " FirstResult", s + " SecondResult")
    .delay(10, TimeUnit.SECONDS, scheduler))
  .toList()
  .doOnSuccess(s -> actualOutput.addAll(s))
  .subscribe();

scheduler.advanceTimeBy(1, TimeUnit.MINUTES);

// then
assertThat(actualOutput, hasItems("b FirstResult", "b SecondResult",
  "boo FirstResult", "boo SecondResult",
  "bo FirstResult", "bo SecondResult",
  "book FirstResult", "book SecondResult",
  "books FirstResult", "books SecondResult"));

順序はすべての実行で常に同じであるとは限らないことに注意してください。

3. switchMap

switchMap演算子はflatMapと似ていますが、最新の観測量のみの結果を保持し、前の観測量を破棄する点が異なります。

部分的なクエリ文字列ではなく、最後の完全に形成された単語(この場合は「本」)のみの検索結果を取得するという要件を変更しましょう。 これを実現するために、switchMapを使用できます。

上記のコード例でflatMapswitchMapに置き換えるだけの場合、次のアサーションが有効になります。

assertEquals(2, actualOutput.size());
assertThat(actualOutput, hasItems("books FirstResult", "books SecondResult"));

ここにあるように、ソースオブザーバブルからの最新の入力項目を含む単一のオブザーバブルのみを取得しました。 以前の結果はすべて破棄されました。

4. 結論

要約すると、switchMapflatMapとは異なり、ソースObservableによって発行された最新のアイテムに提供された関数を適用した出力のみを保持します。一方、flatMapはすべてを保持します。結果を返し、順序を保証せずにインターリーブされた方法でそれらを返します。

いつものように、この記事で使用されているコードはover on GitHubで利用できます。