Встречается на 37% собеседований по Java

Что такое функциональный интерфейс

Функциональный интерфейс — это интерфейс, который содержит ровно один абстрактный метод. Такие интерфейсы служат основой для лямбда-выражений и ссылок на методы, появившихся в Java 8, позволяя передавать поведение как данные и делая код более лаконичным. Например, стандартный интерфейс Predicate<T> принимает объект типа T и возвращает boolean, что удобно для проверки условий.

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

Лямбда-выражение может быть использовано там, где ожидается функциональный интерфейс. Компилятор автоматически связывает лямбду с единственным абстрактным методом интерфейса. Например, Predicate<String> можно реализовать так:

java
Predicate<String> isNotEmpty = s -> !s.isEmpty();
System.out.println(isNotEmpty.test("Hello")); // true
System.out.println(isNotEmpty.test(""));      // false

Здесь лямбда s -> !s.isEmpty() заменяет анонимный класс, реализующий метод test. Это упрощает код и улучшает его читаемость.

Создание собственного функционального интерфейса

Любой интерфейс с одним абстрактным методом автоматически считается функциональным. Чтобы явно указать это намерение и получить проверку на этапе компиляции, используют аннотацию @FunctionalInterface. Она не обязательна, но защищает от случайного добавления второго абстрактного метода.

java
@FunctionalInterface
public interface SimpleFunction {
    int apply(int value);
}

// Использование
SimpleFunction triple = value -> value * 3;
System.out.println(triple.apply(5)); // 15

Важно: интерфейс может содержать статические и default методы — они не считаются абстрактными и не нарушают функциональность. Например, Comparator имеет много default и статических методов, но остаётся функциональным, так как у него один абстрактный метод compare.

Подводные камни

  • Если в интерфейсе объявлено два абстрактных метода, он перестаёт быть функциональным, и лямбда не сработает. Аннотация @FunctionalInterface вызовет ошибку компиляции.
  • Методы, унаследованные от Object (equals, hashCode, toString), не учитываются при подсчёте абстрактных методов, поэтому их наличие не мешает.
  • Не путайте функциональный интерфейс с обычным: обычный интерфейс может иметь много абстрактных методов, но тогда он не поддерживает лямбды.

Когда использовать

Функциональные интерфейсы применяются повсеместно в Stream API, при работе с коллекциями, в асинхронном программировании и для реализации стратегий. Стандартные функциональные интерфейсы из пакета java.util.function покрывают большинство сценариев: Function<T,R>, Consumer<T>, Supplier<T>, Predicate<T> и другие. Собственные интерфейсы создают, когда нужна специфическая сигнатура метода.

Коротко

  • Функциональный интерфейс — это интерфейс с одним абстрактным методом.
  • Лямбда-выражения и ссылки на методы работают только с такими интерфейсами.
  • Аннотация @FunctionalInterface не обязательна, но полезна для проверки и документации.
  • Статические и default методы не нарушают функциональность интерфейса.
как отвечать на вопрос
пример собеседования
фреймворки на собеседовании
типичные вопросы junior
интервью вопросы и ответы