Лямбда-выражение - анонимная функция, которую можно передавать в методы как параметр:
Function<Integer,Integer> sum = (a,b) → a+b;В чём преимущество лямбда-выражений?
Очевидный ответ - в краткости. Раньше чтобы "передать поведение" нужен был отдельный или анонимный класс, а теперь есть переменная с анонимной функцией. Удобно и понятно.
Но у лямбд есть ещё одно интересное свойство. Посмотрим на него на примере обхода коллекций.
В далёкие времена обойти коллекцию можно было двумя способами:
▫️С помощью цикла
▫️Через итератор
Этот подход называется external iteration или внешний обход. Последовательно идём по элементам коллекции и применяем к ним некоторую логику. С коллекцией общаемся через интерфейс. Главный путь оптимизации - оптимизация логики обработки.
Лямбда-выражения поменяли сценарий работы. Теперь мы как бы передаём функцию внутрь структуры данных. Структура данных сама решает, как применить функцию исходя из деталей своей реализации.
Теперь уже логика обработки скрыта за функциональным интерфейсом, а структура данных ей пользуется. Это называется internal iteration или внутренний обход.
Итого у нас разрыв шаблона. Двадцать лет обход коллекций шёл по сценарию
🔸Логика обработки - ведущий игрок, все оптимизации здесь
🔸Структура данных - абстракция, скрыта за интерфейсом
С появлением лямбда выражений и Stream API субъект и объект поменялись местами:
🔹Логика обработки доступна через интерфейс
🔹Структура данных - главная, оптимизации происходят на этом уровне
Теперь работу над коллекцией легко делить между потоками. Раньше это было невозможно - логика обработки могла быть любой и параллелить в каждом случае нужно по-разному. Деление на подзадачи на уровне структуры данных гораздо проще, и теперь у нас есть библиотечный метод parallel() в Stream API.
Понятно, что такой подход применим не только к обходу элементов в коллекции, но и к взаимодействию любых компонентов в целом. Смена ролей часто приводит к свежему взгляду на привычные действия. И в жизни, и в написании кода🙂