Выражения Lambda в Java

Выражения Lambda в Java, представленные в Java SE 8, представляют собой экземпляры функциональных интерфейсов (interfaces) — интерфейсов с единственным абстрактным методом. Они обеспечивают компактный способ записи реализации таких интерфейсов с помощью блока кода.

Основные возможности выражений Lambda

Выражения Lambda реализуют единственную абстрактную функцию и, таким образом, реализуют функциональные интерфейсы. Lambda появились в Java 8 и предоставляют следующие возможности:

  • Функциональные интерфейсы: функциональный интерфейс — это интерфейс, который содержит только один абстрактный метод.
  • Код как данные: возможность передавать функциональность в виде аргумента метода.
  • Независимость от класса: создание функций без необходимости объявления класса.
  • Передача и выполнение: возможность передавать выражения lambda как объекты и выполнять их по запросу.

Пример: Реализация функционального интерфейса с помощью Lambda

Ниже приведена программа на Java, демонстрирующая использование выражения lambda для реализации пользовательского функционального интерфейса.


// Java программа, демонстрирующая выражения Lambda
// для реализации пользовательского функционального интерфейса.

// Пример функционального интерфейса (интерфейс с одним абстрактным методом)
interface FuncInterface
{
    // Абстрактный метод
    void abstractFun(int x);

    // Неабстрактный (или default) метод
    default void normalFun()
    {
       System.out.println("Hello");
    }
}

class Test
{
    public static void main(String args[])
    {
        // выражение lambda для реализации вышеуказанного
        // функционального интерфейса.
        // Этот интерфейс по умолчанию реализует abstractFun()
        FuncInterface fobj = (int x) -> System.out.println(2 * x);

        // Вызов выражения lambda, выводит 10
        fobj.abstractFun(5);
    }
}
Вывод

10

Структура выражения Lambda

Ниже представлена структура выражения Lambda:

Синтаксис выражений Lambda

Выражение Lambda в Java имеет следующий синтаксис:

(список аргументов) -> { тело выражения }

Компоненты:

  • Список аргументов: параметры для выражения lambda.
  • Стрелочный оператор (->): разделяет список параметров и тело.
  • Тело: логика, которая должна выполняться.

Виды параметров в выражениях Lambda

Существует три типа параметров для выражений Lambda:

  1. Lambda без параметров
  2. Lambda с одним параметром
  3. Lambda с несколькими параметрами

1. Lambda без параметров

Синтаксис:

() -> System.out.println(«Lambda без параметров»);

Пример: Ниже приведена программа на Java, демонстрирующая выражение lambda без параметров.


// Java программа, демонстрирующая Lambda без параметров
@FunctionalInterface
interface ZeroParameter {
    void display();
}

public class Geeks {
    public static void main(String[] args) {
        // Lambda без параметров
        ZeroParameter zeroParamLambda = () -> System.out.println(
            "Это выражение lambda без параметров!");

        // Вызов метода
        zeroParamLambda.display();
    }
}
Вывод

Это выражение lambda без параметров!

2. Lambda с одним параметром

Синтаксис:

(p) -> System.out.println(«Один параметр: » + p);

Обратите внимание, что если тип переменной может быть выведен из контекста, круглые скобки вокруг параметра не обязательны.

Пример: Программа на Java демонстрирует использование выражения lambda в двух сценариях с ArrayList.

  • Используется выражение lambda для прохода по всем элементам ArrayList и их вывода.
  • Используется выражение lambda с условием, чтобы выборочно вывести чётные элементы ArrayList.

// Java программа, демонстрирующая простые выражения lambda
import java.util.ArrayList;

class Test {

    public static void main(String args[]) {
        // Создаем ArrayList с элементами {1, 2, 3, 4}
        ArrayList al = new ArrayList();
        al.add(1);
        al.add(2);
        al.add(3);
        al.add(4);

        // Используем lambda для вывода всех элементов
        System.out.println("Элементы ArrayList:");
        al.forEach(n -> System.out.println(n));

        // Используем lambda для вывода только чётных элементов
        System.out.println("Чётные элементы ArrayList:");
        al.forEach(n -> {
            if (n % 2 == 0)
                System.out.println(n);
        });
    }
}
Вывод

Элементы ArrayList:
1
2
3
4
Чётные элементы ArrayList:
2
4

Обратите внимание: в этом примере мы используем выражение lambda с методом forEach(), который внутри работает с функциональным интерфейсом Consumer. Интерфейс Consumer принимает один параметр и выполняет действие с ним.

3. Lambda с несколькими параметрами

Синтаксис:

(p1, p2) -> System.out.println(«Несколько параметров: » + p1 + «, » + p2);

Пример: Программа на Java демонстрирует использование выражения lambda для реализации функционального интерфейса, выполняющего базовые арифметические операции.


@FunctionalInterface
interface Functional {
    int operation(int a, int b);
}

public class Test {

    public static void main(String[] args) {
        // Используем выражения lambda для определения операций
        Functional add = (a, b) -> a + b;
        Functional multiply = (a, b) -> a * b;

        // Используем операции
        System.out.println(add.operation(6, 3));       // Выводит 9
        System.out.println(multiply.operation(4, 5));  // Выводит 20
    }
}

Обратите внимание: выражения Lambda подобны функциям и принимают параметры, как обычные методы.

Распространённые встроенные функциональные интерфейсы

  • Comparable<T>: int compareTo(T o);
  • Comparator<T>: int compare(T o1, T o2);

Эти интерфейсы часто используются для сортировки и сравнений.

Обратите внимание: Другие часто используемые интерфейсы включают Predicate<T> для проверки условий, Function<T, R>, представляющий функцию, принимающую аргумент типа T и возвращающую результат типа R, и Supplier<T> — функцию, которая поставляет результаты.

  1. () -> {};
  2. () -> «geeksforgeeks»;
  3. () -> { return «geeksforgeeks»;};
  4. (Integer i) -> {return «geeksforgeeks» + i;}
  5. (String s) -> {return «geeksforgeeks»;};

Пункты 4 и 5 являются неправильными лямбда-выражениями, остальные — корректны. Подробности:

  1. Это выражение lambda не принимает параметров и возвращает void. Это аналог метода с пустым телом: public void run() { }.
  2. Это выражение lambda не имеет параметров и возвращает строку как выражение.
  3. Это выражение lambda без параметров, возвращает строку с помощью явного оператора return внутри блока.
  4. return — оператор управления потоком. Чтобы сделать это выражение валидным, необходимо использовать фигурные скобки:
    (Integer i) -> { return "geeksforgeeks" + i; }
  5. «geeksforgeeks» — выражение, а не оператор. Чтобы сделать это лямбда-выражение валидным, можно убрать фигурные скобки и точку с запятой:
    (String s) -> "geeksforgeeks"

    Или использовать явный оператор return:

    (String s) -> { return "geeksforgeeks"; }

🔑 Ключевые моменты:

  • Выражения Lambda в Java позволяют компактно реализовывать функциональные интерфейсы — интерфейсы с одним абстрактным методом.
  • Lambda выражения могут иметь ноль, один или несколько параметров и обеспечивают гибкость передачи кода в методы.
  • Функциональные интерфейсы, такие как Comparable и Comparator, широко используются вместе с лямбдами для сортировки и сравнения.
  • При создании лямбд важно правильно оформлять тело и параметры, учитывая необходимость фигурных скобок и операторов return.
  • Выражения Lambda упрощают парадигму функционального программирования в Java, уменьшая количество шаблонного кода и улучшая читаемость.

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *