Что такое лямбда-выражение?
Лямбда-выражение — это компактная запись анонимной функции, которую можно присвоить переменной, передать в метод или вернуть как результат. Лямбда реализует единственный абстрактный метод функционального интерфейса, и по сути является краткой формой анонимного класса.
Аналогия из жизни: лямбда — это записка с инструкцией: «сделай вот это». Вы не создаёте отдельного работника (класс), а просто передаёте листок с заданием тому, кто его выполнит.
Структура лямбда-выражения
Основу составляет лямбда-оператор ->, который разделяет выражение на две части: слева — параметры, справа — тело.
Пример
// Полная форма
(int x, int y) -> { return x + y; }
// Сокращённая форма (вывод типов, одно выражение)
(x, y) -> x + y
// Без параметров
() -> 42
// Один параметр — скобки необязательны
n -> n * n
Особенности использования
- Тип параметров можно не указывать — компилятор выводит их из контекста
- Если тело состоит из одного выражения, фигурные скобки и
returnопускаются - Лямбда не выполняется в момент объявления — это отложенное выполнение (deferred execution)
- Лямбду можно передать в качестве параметра метода
Пример: лямбда как реализация функционального интерфейса
interface Operationable {
int calculate(int x, int y);
}
public static void main(String[] args) {
Operationable operation = (x, y) -> x + y;
int result = operation.calculate(10, 20);
System.out.println(result); // 30
}
Пример: блочная лямбда с return
Operationable operation = (int x, int y) -> {
if (y == 0) {
return 0;
} else {
return x / y;
}
};
Пример: передача лямбды как параметра метода
interface Condition {
boolean isAppropriate(int n);
}
private static int sum(int[] numbers, Condition condition) {
int result = 0;
for (int i : numbers) {
if (condition.isAppropriate(i)) {
result += i;
}
}
return result;
}
public static void main(String[] args) {
System.out.println(
sum(new int[]{0, 1, 0, 3, 0, 5, 0, 7, 0, 9}, n -> n != 0)
);
}
На собеседовании: важно объяснить, что лямбда — не просто синтаксический сахар для анонимного класса. JVM реализует лямбды через
invokedynamic, что позволяет избежать создания отдельного.class-файла. Также подчеркните связь лямбды с функциональными интерфейсами.