Могут ли функциональные интерфейсы в Java принимать аргументы и возвращать значения?

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

Ответ

Да, могут. Стандартные функциональные интерфейсы из пакета java.util.function покрывают основные сценарии:

Интерфейс Сигнатура метода Принимает Возвращает Описание
Function<T,R> R apply(T t) Да (T) Да (R) Преобразует входной тип в выходной.
Consumer<T> void accept(T t) Да (T) Нет Выполняет действие над объектом.
Supplier<T> T get() Нет Да (T) Поставляет (генерирует) значение.
Predicate<T> boolean test(T t) Да (T) Да (boolean) Проверяет условие (утверждение).
UnaryOperator<T> T apply(T t) Да (T) Да (T) Частный случай Function, где вход и выход одного типа.

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

import java.util.function.*;

public class FunctionalExamples {
    public static void main(String[] args) {
        // 1. Function: принимает Integer, возвращает String
        Function<Integer, String> intToHex = num -> "0x" + Integer.toHexString(num);
        System.out.println(intToHex.apply(255)); // 0xff

        // 2. Consumer: принимает String, ничего не возвращает (побочный эффект)
        Consumer<String> logger = msg -> System.out.println("[LOG]: " + msg);
        logger.accept("Приложение запущено");

        // 3. Supplier: не принимает аргументов, возвращает случайное число
        Supplier<Double> randomSupplier = () -> Math.random();
        System.out.println(randomSupplier.get());

        // 4. Predicate: принимает String, возвращает boolean
        Predicate<String> isLong = str -> str.length() > 10;
        System.out.println(isLong.test("Hello")); // false
    }
}

Таким образом, выбор интерфейса зависит от нужной сигнатуры операции.