Разница между map () и flatMap ()

Разница между map () и flatMap ()

1. обзор

APImap() иflatMap() происходят от функциональных языков. В Java 8 вы можете найти их вOptional, Stream и вCompletableFuture (although под немного другим именем).

Streams представляют собой последовательность объектов, а необязательные параметры - это классы, представляющие значение, которое может присутствовать или отсутствовать. Среди других агрегатных операций у нас есть методыmap() иflatMap().

Несмотря на то, что оба имеют одинаковый тип возврата,, они сильно различаются. Давайте объясним эти различия, проанализировав несколько примеров потоков и опций.

Дальнейшее чтение:

Итерировать по карте в Java

Изучите различные способы итерации записей Map в Java.

Read more

Сериализация и десериализация карты с Джексоном

Краткое и практическое руководство по сериализации и десериализации Java Maps с использованием Jackson.

Read more

Как сохранить дубликаты ключей на карте в Java?

Краткое и практическое руководство по обработке дубликатов ключей с использованием мультикарт в Java.

Read more

2. Карта и плоская карта в опциях

Методmap() хорошо работает сOptional - если функция возвращает точный тип, который нам нужен:

Optional s = Optional.of("test");
assertEquals(Optional.of("TEST"), s.map(String::toUpperCase));

Однако в более сложных случаях нам может быть предоставлена ​​функция, которая также возвращаетOptional. В таких случаях использованиеmap() приведет к вложенной структуре, поскольку реализацияmap() выполняет дополнительную внутреннюю оболочку.

Давайте посмотрим на другой пример, чтобы лучше понять эту ситуацию:

assertEquals(Optional.of(Optional.of("STRING")),
  Optional
  .of("string")
  .map(s -> Optional.of("STRING")));

Как мы видим, мы получаем вложенную структуруOptional<Optional<String>>.. Хотя она и работает, она довольно громоздка в использовании и не обеспечивает никакой дополнительной нулевой безопасности, поэтому лучше сохранить плоскую структуру.

Именно в этом нам помогаетflatMap():

assertEquals(Optional.of("STRING"), Optional
  .of("string")
  .flatMap(s -> Optional.of("STRING")));

3. Карта и плоская карта в потоках

Оба метода работают одинаково дляOptional.

Методmap() оборачивает базовую последовательность в экземплярStream, тогда как методflatMap() позволяет избежать вложенной структурыStream<Stream<R>>.

В следующем примереmap() создаетStream, состоящий из результатов применения методаtoUpperCase() к элементам вводаStream:

List myList = Stream.of("a", "b")
  .map(String::toUpperCase)
  .collect(Collectors.toList());
assertEquals(asList("A", "B"), myList);

map() отлично работает в таком простом случае, но что, если у нас есть что-то более сложное, например список списков, в качестве входных данных.

Посмотрим, как это работает:

List> list = Arrays.asList(
  Arrays.asList("a"),
  Arrays.asList("b"));
System.out.println(list);

Этот фрагмент печатает список списков[[a], [b]].. Теперь давайте воспользуемсяflatMap():

System.out.println(list
  .stream()
  .flatMap(Collection::stream)
  .collect(Collectors.toList()));

Результат такого фрагмента будет сведен к[a, b].

МетодTheflatMap() сначала выравнивает входнойStreamStreams доStreamStrings (подробнее о выравнивании см.article) с). После этого он работает аналогично методуmap().

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

Java 8 дает нам возможность использовать методыmap() иflatMap(), которые изначально использовались в функциональных языках.

Мы можем вызывать их вStreams и Optionals. Эти методы помогают нам получить сопоставленные объекты, применяя предоставленную функцию сопоставления.

Как всегда, вы можете ознакомиться с примерами из этой статьиover on GitHub.