Что такое лямбды?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое лямбды?
Лямбда-выражение (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, сблизив язык с функциональным программированием и сделав код более выразительным и компактным.