Ответ
Оба метода являются промежуточными операциями Stream API, но служат для разных сценариев преобразования данных.
| Аспект | map() |
flatMap() |
|---|---|---|
| Назначение | Преобразует каждый элемент потока в один новый элемент. | Преобразует каждый элемент потока в поток элементов, а затем объединяет все потоки в один. |
| Сигнатура | <R> Stream<R> map(Function<T, R> mapper) |
<R> Stream<R> flatMap(Function<T, Stream<R>> mapper) |
| Соотношение | 1 → 1 (один вход → один выход) | 1 → N → 1 (один вход → поток выходов → объединенный поток) |
Пример map(): Преобразование списка строк в список их длин.
List<String> names = List.of("Anna", "Bob", "Charlie");
List<Integer> nameLengths = names.stream()
.map(String::length) // Function<String, Integer>
.toList(); // Результат: [4, 3, 7]
Пример flatMap(): "Разворачивание" списка списков в единый список.
List<List<String>> listOfLists = List.of(
List.of("a", "b"),
List.of("c", "d", "e")
);
List<String> flatList = listOfLists.stream()
.flatMap(List::stream) // Function<List<String>, Stream<String>>
.toList(); // Результат: ["a", "b", "c", "d", "e"]
Практическое применение flatMap():
- Обработка Optional:
Stream<Optional<User>>→Stream<User>. - Разделение строк:
stream.map(line -> line.split("\s+"))вернетStream<String[]>, аflatMap(Arrays::stream)–Stream<String>.