← Назад ко всем вопросам

В чем разница между операциями map и flatMap в Stream API

1️⃣ Как кратко ответить

map преобразует каждый элемент потока в другой объект, сохраняя структуру потока. flatMap не только преобразует элементы, но и "разворачивает" вложенные структуры, объединяя их в один поток.

2️⃣ Подробное объяснение темы

Stream API в Java предоставляет мощные инструменты для работы с последовательностями данных. Две из наиболее часто используемых операций — это map и flatMap. Они позволяют преобразовывать данные в потоке, но делают это по-разному.

Операция map

Операция map применяется к каждому элементу потока и преобразует его в новый элемент. Результатом является поток, содержащий элементы, полученные в результате применения функции к каждому элементу исходного потока. Структура потока остается неизменной — если у вас был поток из N элементов, то после применения map у вас будет поток из N элементов.

Пример использования map:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Stream<Integer> nameLengths = names.stream()
                                   .map(String::length);
  • names.stream(): Создаем поток из списка имен.
  • .map(String::length): Применяем функцию String::length к каждому элементу потока, преобразуя строку в ее длину.
  • nameLengths: Результирующий поток содержит длины имен, но количество элементов остается таким же, как и в исходном потоке.

Операция flatMap

Операция flatMap также применяется к каждому элементу потока, но ожидается, что функция преобразования вернет поток (или другую структуру, которую можно "развернуть"). flatMap объединяет все полученные потоки в один, "разворачивая" их.

Пример использования flatMap:

List<List<String>> nestedList = Arrays.asList(
    Arrays.asList("a", "b"),
    Arrays.asList("c", "d"),
    Arrays.asList("e", "f")
);
​
Stream<String> flatStream = nestedList.stream()
                                      .flatMap(List::stream);
  • nestedList.stream(): Создаем поток из списка списков строк.
  • .flatMap(List::stream): Применяем функцию List::stream к каждому элементу потока, которая преобразует каждый вложенный список в поток. flatMap затем объединяет все эти потоки в один.
  • flatStream: Результирующий поток содержит все строки из всех вложенных списков, объединенные в один поток.

Зачем это нужно

  • map полезен, когда нужно преобразовать элементы потока, сохраняя их количество. Например, преобразование объектов в их свойства или вычисление значений на основе элементов.
  • flatMap необходим, когда работаешь с вложенными структурами данных и нужно их "развернуть". Это часто используется при работе с коллекциями коллекций, где требуется получить плоский поток элементов.

Применение

  • map: Преобразование данных, например, извлечение поля из объекта или изменение типа данных.
  • flatMap: Объединение вложенных структур, например, объединение списков строк в один поток строк.

Таким образом, выбор между map и flatMap зависит от структуры данных, с которой вы работаете, и от того, хотите ли вы сохранить или изменить структуру потока.

Тема: Stream API
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки