Diferença entre o Flatmap e o Switchmap no RxJava

Diferença entre o Flatmap e o Switchmap no RxJava

1. Visão geral

O RxJava fornece vários operadores para transformar itens emitidos por um observável em outros observáveis. Dois dos operadores mais populares sãoflatMap eswitchMap. A diferença entre os dois é muitas vezes difícil de entender para iniciantes em programação reativa.

Para obter uma introdução ao RxJava, consultethis article.

Neste tutorial, vamos entender a diferença percorrendo um exemplo simples.

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. A ordem em que os observáveis ​​são mesclados não tem garantia de ser a mesma que na fonteObservable.

Vejamos um mecanismo de pesquisa como exemplo. Considere que queremos exibir os resultados da pesquisa imediatamente após digitar cada caractere da palavra:

Para simplificar, consideramos a entrada da consulta de pesquisa como uma lista de palavras.

Além disso, sempre retornamos dois resultados de pesquisa para cada palavra.

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

Observe que a ordem nem sempre é a mesma em todas as execuções.

3. switchMap

O operadorswitchMap é semelhante aflatMap, exceto que retém o resultado apenas do último observável, descartando os anteriores.

Vamos mudar nosso requisito, pois queremos obter resultados de pesquisa apenas para a palavra final totalmente formada (neste caso, "livros") e não para as strings de consulta parciais. Para conseguir isso, podemos usarswitchMap.

Se apenas substituirmosflatMap porswitchMap no exemplo de código acima, as seguintes afirmações seriam válidas:

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

Como vemos aqui, só temos um único observável contendo o item de entrada mais recente da fonte observável. Todos os resultados anteriores foram descartados.

4. Conclusão

Para resumir,switchMap difere deflatMap porque retém apenas a saída da aplicação de uma função fornecida ao último item emitido pela fonte Observável,flatMap, por outro lado, retém todos resultados e os retorna de forma intercalada sem garantir a ordem.

Como sempre, o código usado neste artigo está disponívelover on GitHub.