Ответ
Лямбда-выражения — это лаконичная запись для создания экземпляров функциональных интерфейсов (интерфейсов с одним абстрактным методом, например, Runnable, Comparator, Predicate). Они представляют собой блок кода, который можно передавать и выполнять.
Основной синтаксис:
(param) -> expression(param1, param2) -> { statements; return value; }
Примеры в разных контекстах:
-
Сортировка коллекции:
List<String> list = Arrays.asList("z", "a", "c"); // Лямбда как компаратор list.sort((s1, s2) -> s1.compareTo(s2)); -
Обработка событий (GUI):
button.addActionListener(event -> System.out.println("Кнопка нажата!")); -
Собственный функциональный интерфейс:
@FunctionalInterface interface Calculator { int operate(int a, int b); } Calculator add = (x, y) -> x + y; Calculator multiply = (x, y) -> x * y; System.out.println(add.operate(5, 3)); // 8 System.out.println(multiply.operate(5, 3)); // 15
Важные отличия от анонимных классов:
- Краткость: Меньше шаблонного кода.
- Производительность: Нет накладных расходов на создание нового класса (хотя может использовать
invokedynamic). - Область видимости: Лямбда не интродуцирует новый уровень области видимости для имен переменных.
Ответ 18+ 🔞
Слушай, а вот эти лямбда-выражения в Java — это ж, блядь, просто песня, а не фича! Вместо того чтобы городить огород с анонимными классами на три экрана, ты пишешь пару символов и — вуаля, всё работает. Ёперный театр, удобно же!
Вот смотри, по сути, это просто короткий способ сделать экземпляр какого-нибудь функционального интерфейса. Это такой интерфейс, у которого один-единственный абстрактный метод, типа Runnable или Comparator. И лямбда — это и есть реализация этого метода, записанная в стиле «взял и написал».
Как это выглядит, эта ваша лаконичность:
(параметр) -> выражение(парам1, парам2) -> { вот тут код; return чё-нибудь; }
Ну и давай живые примеры, а то занудствовать начнём:
-
Сортировка, например. Раньше писали компаратор на полстраницы, а теперь:
List<String> list = Arrays.asList("z", "a", "c"); // Всё, блядь, сортировка готова. Красота! list.sort((s1, s2) -> s1.compareTo(s2)); -
Кнопку нажали — событие обработали. Раньше слушателя накручивали, а теперь:
button.addActionListener(event -> System.out.println("Кнопка нажата, ёпта!"));Чих-пых — и в продакшен!
-
А если свой интерфейс функциональный захотел? Да пожалуйста!
@FunctionalInterface interface Calculator { int operate(int a, int b); // Один метод — и ты король! } // И вот тебе две реализации, хоть складывай, хоть умножай Calculator add = (x, y) -> x + y; Calculator multiply = (x, y) -> x * y; System.out.println(add.operate(5, 3)); // 8 System.out.println(multiply.operate(5, 3)); // 15
А чем это лучше старого доброго анонимного класса? Да всем, блядь!
- Краткость. Не надо писать
new Интерфейс() { public void method() {...}}. Просто стрелочка и всё. - Производительность. Там под капотом умные штуки,
invokedynamic, не создаётся лишний класс просто так. Хотя, честно, иногда пофиг. - Область видимости. Вот это важно! Лямбда не создаёт свой новый мирок для переменных, как анонимный класс. Она видит всё вокруг, что в текущем методе происходит. Меньше геморроя, короче.
В общем, вещь. Сначала непривычно, а потом, как втянешься, обратно на анонимные классы смотреть не захочешь, как на лапти.