Как работает метод `flatMap` со списком `Long` внутри объекта в Java Stream API?

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

Ответ

Метод flatMap преобразует каждый элемент исходного потока в новый поток, а затем объединяет ("разворачивает") все эти потоки в один плоский поток.

При применении к объекту, содержащему List<Long>, flatMap извлекает этот список и создает из его элементов единый Stream<Long>.

Пример:

class Container {
    List<Long> values = List.of(10L, 20L, 30L);
}

Container container = new Container();
List<Long> result = Stream.of(container)
        .flatMap(c -> c.values.stream()) // Преобразуем Container в Stream<Long>
        .collect(Collectors.toList());
// result = [10, 20, 30]

Важные моменты:

  • Обработка null: Если список values может быть null, это вызовет NullPointerException. Необходима защита:
    .flatMap(c -> c.values != null ? c.values.stream() : Stream.empty())
  • Пустой список: Если список пуст, flatMap просто не добавит элементов в результирующий поток.
  • Глубина: flatMap работает на один уровень вложенности. Для структур вида List<List<Long>> потребуется цепочка flatMap.