Differenza tra Flatmap e Switchmap in RxJava

1. Panoramica

RxJava fornisce vari operatori per trasformare gli elementi emessi da un osservabile in altri osservabili. Due degli operatori più popolari sono flatMap e switchMap . La differenza tra i due è spesso difficile da capire per i principianti nella programmazione reattiva.

Per un'introduzione a RxJava, fare riferimento a questo articolo.

In questo tutorial, capiremo la differenza eseguendo un semplice esempio.

2. flatMap

L' operatore flatMap converte ogni elemento restituito da una sorgente osservabile in un osservabile indipendente utilizzando la funzione fornita e quindi unisce tutte le osservabili in un unico osservabile . Non è garantito che l'ordine in cui le osservabili vengono unite sia lo stesso della fonte Observable.

Prendiamo un motore di ricerca come esempio. Considera che vogliamo visualizzare i risultati della ricerca immediatamente dopo aver digitato ogni carattere della parola:

Per semplicità, abbiamo preso l'input della query di ricerca come un elenco di parole.

Inoltre, restituiamo sempre due risultati di ricerca per ogni parola.

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

Tieni presente che l'ordine non è sempre lo stesso ad ogni corsa.

3. switchMap

L' operatore switchMap è simile a flatMap , tranne per il fatto che conserva solo il risultato dell'ultima osservabile, scartando i precedenti.

Modifichiamo la nostra esigenza in quanto vogliamo ottenere risultati di ricerca solo per la parola finale completamente formata (in questo caso, "libri") e non per le stringhe di query parziali. Per ottenere ciò, possiamo utilizzare switchMap .

Se sostituiamo semplicemente flatMap con switchMap nell'esempio di codice sopra, le seguenti asserzioni sarebbero valide:

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

Come vediamo qui, abbiamo solo un singolo osservabile contenente l'ultimo elemento di input dalla sorgente osservabile. Tutti i risultati precedenti sono stati scartati.

4. Conclusione

Per riassumere, switchMap differisce da flatMap in quanto conserva solo l'output dell'applicazione di una funzione fornita all'ultimo elemento emesso dalla sorgente Observable, flatMap , d'altra parte, conserva tutti i risultati e li restituisce in modo interleaved senza garantire l'ordine.

Come sempre, il codice utilizzato in questo articolo è disponibile su GitHub.