Какой функциональный интерфейс используется в методе `forEach()` для коллекций в Java?

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

Ответ

Метод forEach() для коллекций (унаследованный от Iterable) принимает в качестве аргумента функциональный интерфейс Consumer<T>.

Характеристики Consumer<T>:

  • Единственный абстрактный метод: void accept(T t) — выполняет действие над переданным объектом.
  • Возвращаемое значение: void (не возвращает результат).
  • Назначение: Выполнение side-effect операции (действия с побочным эффектом) для каждого элемента, например, вывод в консоль или изменение внешнего состояния.

Примеры использования:

List<String> names = List.of("Alice", "Bob", "Charlie");

// 1. Через лямбда-выражение
names.forEach(name -> System.out.println(name));

// 2. Через method reference (наиболее идиоматично)
names.forEach(System.out::println);

// 3. Сложное действие
List<String> modifiedList = new ArrayList<>();
names.forEach(name -> modifiedList.add("Mr. " + name));

Для примитивных специализаций потоков (IntStream, LongStream, DoubleStream) существуют соответствующие интерфейсы: IntConsumer, LongConsumer, DoubleConsumer.