Lambda-выражения

Тема дорожной карты · Java

Lambda-выражения — это анонимные функции, введённые в Java 8, позволяющие программировать в функциональном стиле, передавая поведение как данные и значительно сокращая шаблонный код по сравнению с анонимными внутренними классами. Lambda-выражение нацелено на функциональный интерфейс — любой интерфейс с единственным абстрактным методом, такой как Runnable, Comparator, Predicate, Function или Consumer из java.util.function — и записывается с использованием лаконичного синтаксиса (params) -> body. Lambda-выражения являются основой Stream API, обеспечивая выразительные конвейеры вида list.stream().filter(x -> x > 0).map(Object::toString).collect(Collectors.toList()), объединяющие Generics, Collections и функциональную компоновку. JVM реализует Lambda-выражения через байткод invokedynamic и LambdaMetafactory, генерирующий эффективные адаптеры точек вызова во время выполнения без создания отдельных файлов .class для каждой лямбды. Владение Lambda-выражениями является фундаментом для работы с современными возможностями Java, включая Stream API, Optional, CompletableFuture и реактивные фреймворки, построенные на функциональных интерфейсах JDK.

Как это работает

Lambda-выражения покрывает generics (параметры типа: class Box<T>, List<String>, Map<K, V>), wildcards (? extends, ? super, правило PECS), функциональные интерфейсы (один abstract-метод: Function, Consumer, Supplier, Predicate), лямбды (x -> x.toUpperCase()), method references (String::toUpperCase), Stream API. Type erasure означает, что generic-инфа исчезает на рантайме — работает на compile-time, но List<String>.class тот же, что List<Integer>.class.

Когда применять

Stream API — для трансформаций (.filter().map().collect()) когда intent яснее цикла. Generics — в API библиотек чтобы протолкнуть type-safety вызывающим. Применяйте PECS (Producer Extends, Consumer Super) при проектировании wildcards. Не over-engineer — Function<? super T, ? extends R> иногда правильный ответ, иногда запах.

Типичные ошибки

Ловушки Lambda-выражения: List rawList = new ArrayList() (raw-типы — обходят generics, ломают type-safety); злоупотребление Stream .peek() для side-эффектов (это для дебага — forEach если нужны side-эффекты); stateful-лямбды (parallel streams + mutable shared state = race); instanceof + cast вместо pattern matching (Java 21+).

Связанные понятия

Полезные ресурсы

Проверить знания (1)

Загрузка вопросов…