Разница между Flatmap и Switchmap в RxJava

Разница между Flatmap и Switchmap в RxJava

1. обзор

RxJava предоставляет различные операторы для преобразования элементов, испускаемых наблюдаемой, в другие наблюдаемые. Два самых популярных оператора -flatMap иswitchMap. Разницу между ними часто трудно понять новичкам в реактивном программировании.

Для введения в 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..

Возьмем для примера поисковую систему. Учтите, что мы хотим отображать результаты поиска сразу после того, как введем каждый символ слова:

Для простоты мы взяли ввод поискового запроса как список слов.

Кроме того, мы всегда возвращаем два результата поиска для каждого слова.

// 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.

Если мы просто заменимflatMap наswitchMap в приведенном выше примере кода, следующие утверждения будут действительными:

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

Как мы видим здесь, у нас есть только одна наблюдаемая, содержащая самый последний элемент ввода из наблюдаемой исходной. Все предыдущие результаты были отброшены.

4. Заключение

Подводя итог,switchMap отличается отflatMap тем, что он сохраняет только результат применения предоставленной функции к последнему элементу, выданному исходным Observable,flatMap, с другой стороны, сохраняет все результатов и возвращает их в чередующемся порядке без гарантии порядка.

Как всегда, код, использованный в этой статье, доступенover on GitHub.