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

Что такое flatMap в Stream API?

1.3 Junior🔥 231 комментариев
#Stream API и функциональное программирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

flatMap в Stream API

flatMap — это промежуточная операция в Stream API, которая применяет функцию-маппер к каждому элементу потока и затем объединяет (flattens) все полученные потоки в один результирующий поток. Название происходит от сочетания "flat" (плоский) и "map" (преобразование).

Сигнатура метода

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

Метод принимает функцию, которая преобразует элемент типа T в Stream типа R, а затем все эти потоки объединяются в единый поток результирующих элементов.

Как работает flatMap

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

// map: преобразует каждый элемент в один новый элемент
List<Integer> numbers = Arrays.asList(1, 2, 3);
Stream<Integer> mapped = numbers.stream()
    .map(x -> x * 2);  // 2, 4, 6

// flatMap: каждый элемент может генерировать несколько элементов
Stream<Integer> flattened = numbers.stream()
    .flatMap(x -> Stream.of(x, x * 2));  // 1, 2, 2, 4, 3, 6

Практические примеры

Пример 1: Развертывание списков

List<List<String>> listOfLists = Arrays.asList(
    Arrays.asList("a", "b"),
    Arrays.asList("c", "d"),
    Arrays.asList("e", "f")
);

List<String> flattened = listOfLists.stream()
    .flatMap(List::stream)
    .collect(Collectors.toList());
// Результат: [a, b, c, d, e, f]

Пример 2: Генерирование нескольких значений на один элемент

List<Integer> numbers = Arrays.asList(1, 2, 3);

List<Integer> result = numbers.stream()
    .flatMap(x -> Stream.of(x, x * x, x * x * x))
    .collect(Collectors.toList());
// Результат: [1, 1, 1, 2, 4, 8, 3, 9, 27]

Пример 3: Преобразование String в символы

List<String> words = Arrays.asList("Hello", "World");

List<String> chars = words.stream()
    .flatMap(word -> word.chars().boxed().map(String::valueOf))
    .collect(Collectors.toList());
// Результат: [H, e, l, l, o, W, o, r, l, d]

flatMap vs map

List<Integer> numbers = Arrays.asList(1, 2);

// map возвращает Stream<Stream<Integer>>
Stream<Stream<Integer>> mapResult = numbers.stream()
    .map(x -> Stream.of(x, x * 2));

// flatMap возвращает Stream<Integer>
Stream<Integer> flatMapResult = numbers.stream()
    .flatMap(x -> Stream.of(x, x * 2));

Другие варианты flatMap

// flatMapToInt, flatMapToLong, flatMapToDouble
List<String> numbers = Arrays.asList("1,2,3", "4,5,6");

int sum = numbers.stream()
    .flatMapToInt(str -> Arrays.stream(
        Arrays.stream(str.split(","))
            .mapToInt(Integer::parseInt)
            .toArray()
    ))
    .sum();

Важные особенности

  1. Ленивость вычисления: flatMap не выполняется до терминальной операции (collect, forEach и т.д.)
  2. Порядок элементов: элементы обрабатываются в порядке, заданном функцией mapper
  3. Производительность: flatMap может быть менее эффективен, чем несколько операций map, из-за создания промежуточных потоков
  4. Null-safety: если mapper вернет null вместо Stream, будет NullPointerException

flatMap — мощный инструмент для работы с вложенными структурами данных и преобразования коллекций в Stream API.

Что такое flatMap в Stream API? | PrepBro