← Назад к вопросам

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

2.3 Middle🔥 111 комментариев
#Docker, Kubernetes и DevOps#JVM и управление памятью

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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

Лямбда-выражение (lambda expression) — это анонимная функция, введённая в Java 8, которая позволяет писать код более кратко и функционально. Это выражение представляет собой реализацию функционального интерфейса (интерфейса с одним методом).

Синтаксис лямбды

Основная форма лямбды:

(параметры) -> тело

Примеры:

// Без параметров
() -> System.out.println("Hello World")

// Один параметр (скобки опциональны)
x -> x * 2
// или
(x) -> x * 2

// Несколько параметров
(a, b) -> a + b

// С типами параметров
(int a, int b) -> a + b

// Блок кода (несколько строк)
(a, b) -> {
    int sum = a + b;
    return sum * 2;
}

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

Лямбды работают только с функциональными интерфейсами — интерфейсами ровно с одним абстрактным методом:

@FunctionalInterface
public interface Calculator {
    int calculate(int a, int b);
}

// Использование
Calculator add = (a, b) -> a + b;
Calculator multiply = (a, b) -> a * b;

int result1 = add.calculate(5, 3);      // 8
int result2 = multiply.calculate(5, 3); // 15

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

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

Java предоставляет стандартные функциональные интерфейсы в пакете java.util.function:

// Predicate<T> — проверка условия
Predicate<Integer> isPositive = x -> x > 0;
boolean result = isPositive.test(5); // true

// Function<T, R> — преобразование
Function<String, Integer> stringLength = s -> s.length();
int length = stringLength.apply("Java"); // 4

// Consumer<T> — выполнение действия
Consumer<String> printer = x -> System.out.println(x);
printer.accept("Hello");

// Supplier<T> — поставка значения
Supplier<String> greeting = () -> "Hello World";
String message = greeting.get();

// BiFunction<T, U, R> — функция с двумя параметрами
BiFunction<Integer, Integer, Integer> sum = (a, b) -> a + b;
int result = sum.apply(5, 3); // 8

Применение в Streams API

Лямбды особенно мощны с Stream API:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

// Фильтрация
List<Integer> evenNumbers = numbers.stream()
    .filter(n -> n % 2 == 0)
    .collect(Collectors.toList()); // [2, 4]

// Трансформация
List<Integer> doubled = numbers.stream()
    .map(n -> n * 2)
    .collect(Collectors.toList()); // [2, 4, 6, 8, 10]

// Действие над каждым элементом
numbers.forEach(n -> System.out.println(n));

Различие между лямбдой и анонимным классом

// Анонимный класс (Java 7 и ранее)
Calculator calc = new Calculator() {
    @Override
    public int calculate(int a, int b) {
        return a + b;
    }
};

// Лямбда (Java 8+) — намного короче
Calculator calc = (a, b) -> a + b;

Захват переменных (Variable Capture)

Лямбда может использовать переменные из внешней области видимости, но только effectively final (не изменяются после инициализации):

int multiplier = 2; // effectively final
// multiplier = 5; // ошибка — нельзя менять

Function<Integer, Integer> multiply = x -> x * multiplier;
System.out.println(multiply.apply(5)); // 10

Преимущества лямбд

  • Краткость кода — меньше boilerplate
  • Читаемость — ясное выражение намерения
  • Функциональный стиль — возможность программировать функционально
  • Параллелизм — удобство работы с параллельными потоками
  • Лучшая производительность — оптимизация JVM

Ограничения

  • Работают только с функциональными интерфейсами
  • Не могут иметь состояние
  • Переменные из внешней области должны быть effectively final
  • Сложная логика становится нечитаемой

Лямбды стали поворотным моментом в Java, сблизив язык с функциональным программированием и сделав код более выразительным и компактным.