# Лямбда-выражения в Java: синтаксис и применение
Table of Contents
Лямбда-выражения в Java: синтаксис и применение
Введение
Лямбда-выражения, появившиеся в Java 8, значительно упростили написание кода, особенно при работе с функциональными интерфейсами. Они позволяют передавать функции в качестве аргументов, сокращают объем кода и делают его более читаемым. В этой статье мы разберем синтаксис лямбда-выражений, их связь с функциональными интерфейсами и примеры использования.
Синтаксис лямбда-выражений
Базовая форма
Лямбда-выражение состоит из:
- Списка параметров (в скобках или без).
- Стрелки
->. - Тела (выражение или блок кода).
Общий вид:
(параметры) -> { тело }Варианты синтаксиса
-
Без параметров
Используются пустые скобки:() -> System.out.println("Hello, World!"); -
Один параметр
Скобки можно опустить:x -> x * x; -
Несколько параметров
Обязательны скобки:(a, b) -> a + b; -
Указание типов параметров
Типы можно указать явно:(int x, int y) -> x + y;
Тело лямбда-выражения
-
Простое тело (одна строка):
Фигурные скобки иreturnне требуются:(String s) -> s.length(); -
Блочное тело (несколько операторов):
Используются фигурные скобки и явныйreturn:(x, y) -> {int sum = x + y;return sum;};
Функциональные интерфейсы
Лямбда-выражения работают с функциональными интерфейсами — интерфейсами с одним абстрактным методом. Примеры:
-
Runnable(методrun()):Runnable task = () -> System.out.println("Task executed"); -
Comparator<T>(методcompare(T o1, T o2)):Comparator<Integer> comp = (a, b) -> a - b; -
Собственный интерфейс:
@FunctionalInterfaceinterface Calculator {int calculate(int a, int b);}Calculator add = (a, b) -> a + b;
Примеры использования
1. Со Stream API
Лямбды активно используются для обработки коллекций:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
// Фильтрация и выводnumbers.stream() .filter(n -> n % 2 == 0) .forEach(System.out::println); // 2, 4
// Преобразование элементовList<Integer> squares = numbers.stream() .map(x -> x * x) .collect(Collectors.toList());2. Обработка событий
В GUI-приложениях (например, Swing):
button.addActionListener(e -> System.out.println("Кнопка нажата!"));Захват переменных
Лямбды могут использовать переменные из внешней области видимости, если они effectively final (не изменяются после инициализации):
int threshold = 10;list.forEach(x -> { if (x > threshold) { // Захватывается переменная threshold System.out.println(x); }});Ссылки на методы
Лямбды можно заменять ссылками на методы для еще большей краткости:
- Статический метод:
ClassName::method. - Метод экземпляра:
instance::method. - Конструктор:
ClassName::new.
Пример:
List<String> words = Arrays.asList("a", "b", "c");words.forEach(System.out::println); // Эквивалентно x -> System.out.println(x)Ограничения и ошибки
-
Несовместимость с функциональными интерфейсами
Лямбда должна соответствовать сигнатуре метода интерфейса:// Ошибка: метод ожидает два параметраCalculator invalid = a -> a + 10; -
Пропуск
returnв блоке
В блочном телеreturnобязателен:(x, y) -> { x + y; }; // Ошибка: нет return -
Использование не-final переменных:
int count = 0;Runnable task = () -> count++; // Ошибка: count не effectively final
Заключение
Лямбда-выражения в Java — мощный инструмент для написания лаконичного и выразительного кода. Они упрощают работу с функциональными интерфейсами, Stream API и асинхронными задачами. Понимание их синтаксиса и особенностей позволяет эффективно использовать современные возможности Java, сокращая объем шаблонного кода.