Что такое лямбда-выражение в Java?

Ответ

Лямбда-выражение — это краткий синтаксис для реализации функционального интерфейса (интерфейса с одним абстрактным методом). Оно позволяет передавать код как данные.

Синтаксис: (параметры) -> выражение или (параметры) -> { операторы; }

Пример: Замена анонимного класса

// До Java 8: анонимный класс
Runnable oldRunnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello from anonymous class");
    }
};

// С лямбдой
Runnable newRunnable = () -> System.out.println("Hello from lambda");

Ключевые особенности:

  1. Типизация: Компилятор выводит типы параметров из контекста (контекст целевого типа).
  2. Доступ к переменным: Может захватывать final или effectively final переменные из окружающей области видимости.
  3. Область видимости: Не создает новую область видимости для this и super — они ссылаются на enclosing-класс.

Практическое использование с Stream API:

List<String> names = Arrays.asList("Anna", "Bob", "John");
// Фильтрация с помощью лямбды
List<String> filtered = names.stream()
                             .filter(name -> name.startsWith("A")) // Предикат
                             .map(String::toUpperCase)            // Ссылка на метод
                             .collect(Collectors.toList()); // ["ANNA"]

Ответ 18+ 🔞

А, лямбды, ёпта! Ну это ж просто пиздец как удобно, если разобраться. Смотри, вот раньше-то, блядь, как было: хотел ты кусочек кода передать — писал целый анонимный класс, этот цирк с конями, на три строчки кода — десять строчек объявлений! Прям волнение ебать, как вспомнишь.

А теперь — красота, блядь. Взял и написал (параметры) -> выражение. Всё, пиздец. Компилятор сам, хитрая жопа, догадается, что ты от него хочешь.

Вот смотри, как раньше мучались:

// Это ж пиздец какой овердохуища код, блядь!
Runnable oldRunnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello from anonymous class");
    }
};

А теперь, внатуре:

// Ёбушки-воробушки, одна строчка!
Runnable newRunnable = () -> System.out.println("Hello from lambda");

Чувак, ты представляешь? Всю эту хуйню с new, @Override — нахуй выкинул! Просто стрелочка и поехали.

А главные фишки, блядь, вот какие:

  1. Типы. Ты можешь их даже не писать, компилятор и так всё видит. Он же не слепой, сука. Сам выведет из контекста, что к чему.
  2. Переменные снаружи. Можешь ловить переменные извне, но только если они final или effectively final (то есть не меняются, блядь). Как поймал — так и пользуешься.
  3. this и super. Вот тут внимание, ёпта! Они внутри лямбды ссылаются на внешний класс, а не на саму лямбду. Не создаётся новый объект, поэтому и путаницы нет.

А где это всё, блядь, реально пригождается? Да везде, сука! Особенно с этими вашими Stream API, которые всех задолбали, но они охуенные.

Смотри, был у тебя список имён:

List<String> names = Arrays.asList("Anna", "Bob", "John");

Хочешь отфильтровать только тех, кто на "A" начинается, да ещё и большими буквами сделать? Раньше бы циклы писал, итераторы... Пиздец. А сейчас:

List<String> filtered = names.stream()
                             .filter(name -> name.startsWith("A")) // Вот она, лямбда-проверка!
                             .map(String::toUpperCase)            // А это ссылка на метод, тоже прикольная штука
                             .collect(Collectors.toList()); // И собираем обратно
// Получится ["ANNA"], блядь!

Короче, лямбды — это как взять и выкинуть из кода тонну ненужного строительного мусора. Остаётся только суть, чистая логика. Сначала, конечно, мозг ебёт, привыкнуть надо. Но как втянешься — обратно уже не захочешь, в рот меня чих-пых!