Ответ
Лямбда-выражения в Java (с версии 8+) — это краткая форма записи анонимных функций, реализующих единственный абстрактный метод функционального интерфейса. Они позволяют писать более компактный и выразительный код, особенно в контексте Stream API и обработки коллекций.
Синтаксис: (параметры) -> { тело } или (параметры) -> выражение.
Примеры:
// 1. Сортировка списка с помощью лямбды
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.sort((a, b) -> a.compareTo(b));
// 2. Использование с Stream API
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
List<Integer> squares = numbers.stream()
.map(n -> n * n) // Лямбда как Function
.collect(Collectors.toList()); // [1, 4, 9, 16, 25]
// 3. Запуск потока (Runnable)
new Thread(() -> System.out.println("Запуск из лямбды")).start();
Ключевые особенности:
- Целевой тип: Тип лямбды определяется из контекста (ожидаемый функциональный интерфейс:
Comparator,Predicate,Function,Consumerи т.д.). - Захват переменных: Лямбда может использовать
effectively finalпеременные из окружающей области видимости (локальные переменные, которые не изменяются после инициализации). - Ссылки на методы: Часто могут быть заменены на более лаконичные ссылки на методы (
String::compareTo,System.out::println).
Функциональные интерфейсы (пакет java.util.function) — основа для лямбд:
Predicate<T>— проверка условия (t -> t > 5).Function<T,R>— преобразование объекта (s -> s.length()).Consumer<T>— выполнение действия (obj -> System.out.println(obj)).Supplier<T>— поставщик значения (() -> new Object()).
Ответ 18+ 🔞
Да ты посмотри, что эти умники в Java придумали! Лямбда-выражения, блядь. Ну, в рот меня чих-пых, раньше же писали эти анонимные классы на пол-экрана, а теперь — бац, и в одну строчку!
Представь, был у тебя Comparator, и писал ты его так, что мама не горюй. А теперь? (a, b) -> a.compareTo(b). И всё, пиздец! Красота, а не жизнь.
Синтаксис-то у них, ёпта, простой до безобразия: либо (параметры) -> { тело }, либо если одна команда — (параметры) -> выражение. Хуй с горы, и понятно.
Вот смотри, как они в деле:
// 1. Сортировка списка — раньше бы писал целый класс, а теперь...
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.sort((a, b) -> a.compareTo(b)); // И делов-то!
// 2. Stream API — это вообще отдельная песня, блядь. Магия.
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
List<Integer> squares = numbers.stream()
.map(n -> n * n) // Взял число и нахуярил квадрат, всё
.collect(Collectors.toList()); // [1, 4, 9, 16, 25]
// 3. Поток запустить — вообще смешно стало
new Thread(() -> System.out.println("Запуск из лямбды")).start();
А теперь про подводные, блядь, камни, чтоб ты знал:
- Целевой тип: Лямбда сама по себе — как беспризорник, блядь. Тип её определяется по тому, куда её суют. Ждёт от тебя
Comparator— ну, значит, она и будетComparator. Умная жопа, короче. - Захват переменных: Может она извне переменные брать, да. Но только те, что
effectively final— то есть которые после создания не ебёшь. Иначе — компляйн-тайм, дружок. - Ссылки на методы: А ещё, сука, можно ещё короче! Вместо
s -> s.length()написатьString::length. Вообще ахуеть.
Основа всего этого цирка — функциональные интерфейсы (из java.util.function). Запомни этих уродцев, они везде лезут:
Predicate<T>— проверит что-то (t -> t > 5). Правда или нет, бля?Function<T,R>— превратит одно в другое (s -> s.length()). Алхимик, ёпта.Consumer<T>— сделает что-то с объектом, но ничего не вернёт (obj -> System.out.println(obj)). Просто потребитель, манда с ушами.Supplier<T>— ничего не принимает, но что-то выдаёт (() -> new Object()). Как баба на сносях, только без истерик.
Вот и вся магия. Сначала охуеешь, а потом такой: "Да как же я раньше без этого жил, блядь?". Главное — не переборщить, а то код такой напишешь, что сам через неделю разбираться не захочешь.