Введення в лямбда-вирази. Вбудовані функціональні інтерфейси

Прокрутити вниз

Введення в лямбда-вирази. Вбудовані функціональні інтерфейси

Введення в лямбда-вирази

Лямбда-вирази — це новий синтаксичний елемент, доданий у Java 8, який дозволяє писати коротші та більш читабельні функціональні вирази, особливо в контексті функціонального програмування. Лямбда-вирази використовуються для передачі функцій як параметрів методів або для створення анонімних функцій.

Основний синтаксис лямбда-виразів

(параметри) -> {тіло виразу}

  • Параметри: перелік параметрів, який передається лямбда-виразу (може бути порожнім).
  • Оператор `->`: розділяє список параметрів та тіло виразу.
  • Тіло виразу: це код, який виконується при виклику лямбда-виразу.

Приклади:

1. Лямбда без параметрів:
() -> System.out.println(“Hello, World!”);

2. Лямбда з одним параметром:
x -> x * x

3. Лямбда з кількома параметрами:
(x, y) -> x + y

4. Лямбда з блоком коду:
Якщо лямбда-вираз містить кілька операторів, необхідно використовувати фігурні дужки `{}`.

(x, y) -> {
int result = x + y;
return result;
}

Лямбда-вирази та функціональні інтерфейси

Лямбда-вирази можуть використовуватися лише з функціональними інтерфейсами. Це інтерфейси, які містять тільки один абстрактний метод. Їх часто називають SAM (Single Abstract Method) інтерфейсами. Лямбда-вираз дозволяє реалізувати цей єдиний метод у скороченій формі.

Приклад функціонального інтерфейсу:

@FunctionalInterface
interface Calculator {
int calculate(int x, int y);
}

Використання лямбда-виразу для реалізації цього інтерфейсу:

Calculator add = (x, y) -> x + y;
Calculator multiply = (x, y) -> x * y;

int sum = add.calculate(5, 3); // 8
int product = multiply.calculate(5, 3); // 15

Вбудовані функціональні інтерфейси

Java 8 вводить кілька стандартних функціональних інтерфейсів, які можна використовувати з лямбда-виразами. Всі вони знаходяться в пакеті `java.util.function`.

1. Function<T, R>

Цей інтерфейс приймає один параметр типу `T` і повертає результат типу `R`. Метод: `R apply(T t)`.

Приклад:

Function<Integer, String> intToString = (i) -> “Number: ” + i;
System.out.println(intToString.apply(5)); // Output: “Number: 5”

2. Consumer<T>

Приймає один аргумент типу `T` і не повертає результату. Використовується для виконання операцій над переданим параметром. Метод: `void accept(T t)`.

Приклад:

Consumer<String> print = (str) -> System.out.println(str);
print.accept(“Hello, Java!”); // Output: “Hello, Java!”

3. Supplier<T>

Не приймає жодних параметрів, але повертає значення типу `T`. Метод: `T get()`.

Приклад:

Supplier<Double> randomValue = () -> Math.random();
System.out.println(randomValue.get()); // Output: випадкове число

4. Predicate<T>

Приймає один параметр типу `T` і повертає логічне значення (boolean). Метод: `boolean test(T t)`.

Приклад:

Predicate<Integer> isEven = (n) -> n % 2 == 0;
System.out.println(isEven.test(4)); // Output: true
System.out.println(isEven.test(5)); // Output: false

5. BiFunction<T, U, R>

Приймає два параметри типу `T` і `U` та повертає результат типу `R`. Метод: `R apply(T t, U u)`.

Приклад:

BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
System.out.println(add.apply(5, 3)); // Output: 8

6. UnaryOperator<T>

Це спеціальний випадок `Function`, який приймає один аргумент і повертає результат того ж типу. Метод: `T apply(T t)`.

Приклад:

UnaryOperator<Integer> square = (x) -> x * x;
System.out.println(square.apply(4)); // Output: 16

7. BinaryOperator<T>

Це спеціальний випадок `BiFunction`, який приймає два аргументи одного типу і повертає результат того ж типу. Метод: `T apply(T t1, T t2)`.

Приклад:

BinaryOperator<Integer> multiply = (a, b) -> a * b;
System.out.println(multiply.apply(5, 3)); // Output: 15

Приклад використання лямбда-виразів і функціональних інтерфейсів

import java.util.function.*;

public class LambdaExample {
public static void main(String[] args) {
// Function: приймає Integer, повертає String
Function<Integer, String> intToString = (i) -> “Number: ” + i;
System.out.println(intToString.apply(10));

// Consumer: приймає String, нічого не повертає
Consumer<String> print = (s) -> System.out.println(s);
print.accept(“Hello, Consumer!”);

// Supplier: не приймає параметрів, повертає Double
Supplier<Double> randomValue = () -> Math.random();
System.out.println(randomValue.get());

// Predicate: приймає Integer, повертає boolean
Predicate<Integer> isEven = (n) -> n % 2 == 0;
System.out.println(isEven.test(8));

// BiFunction: приймає два Integer, повертає Integer
BiFunction<Integer, Integer, Integer> sum = (a, b) -> a + b;
System.out.println(sum.apply(5, 7));
}
}

Висновок

  • Лямбда-вирази роблять код коротшим і більш читабельним, особливо коли потрібно передати функцію як параметр.
  • Лямбда-вирази працюють лише з функціональними інтерфейсами, які мають один абстрактний метод.
  • Java 8 додає багато вбудованих функціональних інтерфейсів у пакеті `java.util.function`, таких як `Function`, `Predicate`, `Consumer`, `Supplier`, які дозволяють ефективно використовувати лямбда-вирази у різних контекстах.

Введення в лямбда-вирази Лямбди як параметри та результати методів. Вбудовані функціональні інтерфейси