Ответ
Метод flatMap() возвращает новый поток (Stream<R>), являющийся результатом слияния (конкатенации) всех потоков, которые были созданы функцией-маппером для каждого элемента исходного потока.
Как это работает:
- Для каждого элемента исходного
Stream<T>применяется функцияmapper, которая возвращаетStream<R>. - Все эти отдельные потоки
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()).