Skip to content

Theory

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

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

  • Функциональный интерфейс — это интерфейс, который содержит ровно один абстрактный метод.
  • Он может также содержать дефолтные и статические методы.
  • Функциональные интерфейсы используются в контексте лямбда-выражений и ссылок на методы. Пример: интерфейс Runnable с методом run().
  • Для обозначения функционального интерфейса используется аннотация @FunctionalInterface, но её использование необязательно.

Для чего нужна аннотация @FunctionalInterface?

Аннотация @FunctionalInterface используется для явного обозначения интерфейса как функционального. Она служит для следующих целей:

  • Проверка компилятора: Гарантирует, что интерфейс содержит только один абстрактный метод. Если в интерфейсе более одного абстрактного метода, компилятор выдаст ошибку.
  • Документация: Явно показывает, что интерфейс предназначен для использования с лямбда-выражениями или ссылками на методы, что делает код более понятным для разработчиков.

Аннотация необязательна, но её использование рекомендуется для улучшения читаемости и предотвращения ошибок.

Что такое лямбда?

  • Лямбда-выражение в Java — это краткая форма записи анонимного класса, реализующего функциональный интерфейс.
  • Оно позволяет писать функциональный код компактнее, убирая лишние детали, такие как объявление класса и метода.
  • Лямбда-выражения используются для передачи поведения в виде аргументов, чаще всего в функциональных стилях программирования, например, при работе с коллекциями.
  • Лямбда-выражения позволяют писать более выразительный и читаемый код.

Что использовали, когда лямбд не было?

До появления лямбда-выражений в Java (до версии 8), для передачи поведения или функциональности использовались анонимные внутренние классы.

Пример использования анонимного класса вместо лямбда:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("Running");
    }
};

Вместо лямбда-выражений, такой код был громоздким и содержал много шаблонного кода, что делало его менее читаемым. Лямбды пришли на смену анонимным классам, чтобы сделать код более лаконичным и удобным.

Чем лямбда она отличается от анонимного класса?

Лямбда-выражения и анонимные классы в Java имеют схожие цели, но между ними есть несколько ключевых различий:

  1. Синтаксис:
    • Лямбда: Лаконичный и компактный синтаксис, предназначенный для описания функциональности, обычно в одну строку.
    • Анонимный класс: Более громоздкий синтаксис, требующий полного определения класса и его метода.
  2. Создание классов:
    • Лямбда: Не создает нового класса на уровне байт-кода; вместо этого компилятор создает легковесный объект функционального интерфейса.
    • Анонимный класс: Создает новый анонимный класс во время компиляции, что увеличивает размер байт-кода и нагрузку на память.
  3. Использование контекста:
    • Лямбда: Контекст this внутри лямбды ссылается на внешний класс, в котором лямбда определена.
    • Анонимный класс: Контекст this ссылается на сам анонимный класс.
  4. Оптимизация и производительность:
    • Лямбда: Оптимизируется компилятором и JVM с использованием invokedynamic, что позволяет эффективнее управлять памятью и улучшает производительность.
    • Анонимный класс: Менее оптимизирован, так как создает дополнительный класс, что увеличивает накладные расходы.
  5. Тип привязки:
    • Лямбда: Привязывается к функциональному интерфейсу, ограниченному одним абстрактным методом.
    • Анонимный класс: Может реализовать любой интерфейс или расширить любой класс.
  6. Читаемость и поддержка:
    • Лямбда: Более лаконичный и читаемый код, особенно полезен в функциональном программировании.
    • Анонимный класс: Код более громоздкий и трудночитаемый, особенно при сложных выражениях.

В итоге, лямбда-выражения более компактны, эффективны и удобны в использовании, чем анонимные классы, особенно когда речь идет о реализации функциональных интерфейсов.

Stream API

Чт