Unterschied zwischen Flatmap und Switchmap in RxJava

1. Übersicht

RxJava bietet verschiedene Operatoren, um von einem Observable emittierte Elemente in andere Observables umzuwandeln. Zwei der beliebtesten Operatoren sind flatMap und switchMap . Der Unterschied zwischen beiden ist für Anfänger in der reaktiven Programmierung oft schwer zu verstehen.

Eine Einführung in RxJava finden Sie in diesem Artikel.

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

2. flatMap

Der flatMap- Operator konvertiert jedes von einer beobachtbaren Quelle zurückgegebene Element mithilfe der angegebenen Funktion in ein unabhängiges beobachtbares Element und führt dann alle beobachtbaren Elemente zu einem einzigen beobachtbaren Element zusammen . Die Reihenfolge, in der Observables zusammengeführt werden, ist garantiert nicht dieselbe wie in der Quelle Observable.

Nehmen wir als Beispiel eine Suchmaschine. Bedenken Sie, dass wir Suchergebnisse sofort nach Eingabe jedes Zeichens 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 switchMap- Operator ähnelt flatMap , behält jedoch nur das Ergebnis der neuesten beobachtbaren Daten bei und verwirft die vorherigen.

Lassen Sie uns unsere Anforderung dahingehend ändern, dass wir Suchergebnisse nur für das endgültige vollständig formulierte Wort (in diesem Fall „Bücher“) und nicht für die Teilabfragezeichenfolgen erhalten möchten. Um dies zu erreichen, können wir switchMap verwenden .

Wenn wir im obigen Codebeispiel nur flatMap durch switchMap 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 Observable erhalten, die das neueste Eingabeelement aus der beobachtbaren Quelle enthält. Alle vorherigen Ergebnisse wurden verworfen.

4. Fazit

Zusammenfassend unterscheidet sich switchMap von flatMap darin, dass nur die Ausgabe der Anwendung einer bereitgestellten Funktion auf das neueste von der Quelle Observable ausgegebene Element beibehalten wird. FlatMap hingegen behält alle Ergebnisse bei und gibt sie verschachtelt zurück, ohne die Reihenfolge zu garantieren.

Wie immer ist der in diesem Artikel verwendete Code auf GitHub verfügbar.