Для чего используется операция flatMap в Java Stream API?

«Для чего используется операция flatMap в Java Stream API?» — вопрос из категории Java Core, который задают на 22% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

flatMap – это промежуточная операция Stream API, которая решает задачу "выравнивания" (flattening) структур данных. Она преобразует каждый элемент потока в новый поток (Stream), а затем объединяет (конкатенирует) все полученные потоки в один результирующий поток.

Простая аналогия: Если map преобразует [a, b, c] в [A, B, C], то flatMap может преобразовать [[1,2], [3,4]] в [1, 2, 3, 4].

Сигнатура:

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)

Функция-маппер принимает элемент типа T и возвращает Stream<R>.

Ключевые примеры использования:

  1. Преобразование списка списков в плоский список:

    List<List<String>> listOfLists = Arrays.asList(
        Arrays.asList("a", "b"),
        Arrays.asList("c", "d")
    );
    List<String> flatList = listOfLists.stream()
        .flatMap(List::stream) // Преобразуем каждый List в Stream<String>
        .collect(Collectors.toList()); // Результат: [a, b, c, d]
  2. Разделение строк на слова:

    List<String> sentences = Arrays.asList("Hello world", "Java Streams");
    List<String> words = sentences.stream()
        .flatMap(sentence -> Arrays.stream(sentence.split(" "))) // String -> Stream<String>
        .collect(Collectors.toList()); // [Hello, world, Java, Streams]
  3. Обработка Optional (Java 9+):

    List<Optional<String>> optionals = Arrays.asList(Optional.of("A"), Optional.empty(), Optional.of("B"));
    List<String> values = optionals.stream()
        .flatMap(Optional::stream) // Optional.stream() возвращает пустой или одноэлементный поток
        .collect(Collectors.toList()); // [A, B]

Отличие от map:

  • map(Function<T, R>): 1 элемент -> 1 элемент. Результат: Stream<R>.
  • flatMap(Function<T, Stream<R>>): 1 элемент -> N элементов (поток). Результат: Stream<R> (уже "выровненный").

Итог: flatMap – это мощный инструмент для работы с вложенными или составными элементами, когда нужно получить единый поток из множества источников.