Unterschied zwischen Flatmap und Switchmap in RxJava

Unterschied zwischen Flatmap und Switchmap in RxJava

1. Überblick

RxJava bietet verschiedene Operatoren, um Elemente, die von einem Observablen ausgehen, in andere Observablen umzuwandeln. Zwei der beliebtesten Operatoren sindflatMap undswitchMap. Der Unterschied zwischen beiden ist für Anfänger in der reaktiven Programmierung oft schwer zu verstehen.

Eine Einführung in RxJava finden Sie unterthis article.

In diesem Tutorial werden wir den Unterschied anhand eines einfachen Beispiels verstehen.

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. Die Reihenfolge, in der Observables zusammengeführt werden, ist nicht garantiert dieselbe wie in der QuelleObservable.

Nehmen wir als Beispiel eine Suchmaschine. Bedenken Sie, dass wir die Suchergebnisse sofort nach der Eingabe der einzelnen Zeichen des Wortes anzeigen möchten:

Der Einfachheit halber haben wir die Eingabe der Suchabfrage als Liste von Wörtern verwendet.

Außerdem geben wir für jedes Wort immer zwei Suchergebnisse zurück.

// 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"));

Bitte beachten Sie, dass die Reihenfolge nicht bei jedem Lauf gleich ist.

3. switchMap

Der OperatorswitchMap ähneltflatMap, behält jedoch nur das Ergebnis der letzten beobachtbaren Daten bei und verwirft die vorherigen.

Ändern wir unsere Anforderung dahingehend, dass wir Suchergebnisse nur für das endgültige, vollständig geformte Wort (in diesem Fall "Bücher") und nicht für die Teilabfragezeichenfolgen erhalten möchten. Um dies zu erreichen, können wirswitchMap verwenden.

Wenn wir im obigen Codebeispiel nurflatMap durchswitchMap ersetzen, sind die folgenden Aussagen gültig:

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

Wie wir hier sehen, haben wir nur eine einzige Beobachtungsdatei mit dem neuesten Eingabeelement aus der beobachtbaren Quelle. Alle vorherigen Ergebnisse wurden verworfen.

4. Fazit

Zusammenfassend unterscheidet sichswitchMap vonflatMap darin, dass nur die Ausgabe der Anwendung einer bereitgestellten Funktion auf das letzte von der Quelle Observable ausgegebene Element beibehalten wird.flatMap behält andererseits alle bei Ergebnisse und gibt sie verschachtelt zurück, ohne die Bestellung zu garantieren.

Wie immer ist der in diesem Artikel verwendete Codeover on GitHub verfügbar.