С каким функциональным интерфейсом взаимодействует метод map в Java Stream API?

«С каким функциональным интерфейсом взаимодействует метод map в Java Stream API?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Метод map в Stream<T> ожидает аргумент типа Function<? super T, ? extends R>.

Разбор интерфейса:

  • T — тип элемента исходного потока (контравариантный аргумент).
  • R — тип элемента результирующего потока (ковариантный результат).
  • Единственный абстрактный метод (SAM) интерфейса FunctionR apply(T t).

Суть операции: Преобразование каждого элемента потока из типа T в тип R по правилу, заданному функцией (отображение 1:1).

Пример: Преобразование строк в их длины

List<String> names = List.of("John", "Alice", "Bob");
List<Integer> nameLengths = names.stream()
    // Function<String, Integer>: строка -> её длина
    .map(String::length)
    .toList(); // Результат: [4, 5, 3]

Аналоги в других API:

  • Optional<T>: Optional.map(Function<T, R>) преобразует значение внутри Optional, если оно присутствует.
  • CompletableFuture<T>: thenApply(Function<T, R>) для синхронного преобразования результата асинхронной операции.

Важно: map — это промежуточная операция, она не вызывает выполнения потока и возвращает новый ленивый поток с преобразованными элементами.