Что возвращает метод flatMap() в Java Stream API?

«Что возвращает метод flatMap() в Java Stream API?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Как это работает:

  1. Для каждого элемента исходного Stream<T> применяется функция mapper, которая возвращает Stream<R>.
  2. Все эти отдельные потоки Stream<R> объединяются ("сглаживаются") в один конечный Stream<R>.
Ключевые отличия от map(): Критерий map() flatMap()
Возврат функции Отдельный элемент R Поток элементов Stream<R>
Возврат метода Stream<R> Stream<R>
Структура выхода 1-to-1 (один элемент на вход -> один на выход) 1-to-many (один элемент -> много элементов в объединенном потоке)

Пример "разворачивания" вложенной коллекции:

List<List<Integer>> nestedLists = Arrays.asList(
        Arrays.asList(1, 2),
        Arrays.asList(3, 4),
        Arrays.asList(5, 6)
);

// mapper: List<Integer> -> Stream<Integer> (через Collection::stream)
List<Integer> flatList = nestedLists.stream()
        .flatMap(Collection::stream) // Преобразуем каждый внутренний List в Stream
        .toList(); // Результат: [1, 2, 3, 4, 5, 6]
// Без flatMap() пришлось бы вручную итерироваться по внешнему и внутренним спискам.

Важное замечание: Если функция-маппер возвращает null для какого-либо элемента, будет выброшено NullPointerException. Для обработки потенциально пустых значений можно использовать flatMap(e -> e == null ? Stream.empty() : e.stream()).