Функциональный интерфейс - это интерфейс, который определяет только один абстрактный метод.
Чтобы точно определить интерфейс как функциональный, добавлена аннотация @FunctionalInterface, работающая по принципу @Override. Она обозначит замысел и не даст определить второй абстрактный метод в интерфейсе.
Интерфейс может включать сколько угодно default методов и при этом оставаться функциональным, потому что default методы - не абстрактные.
Для чего нужны функциональные интерфейсы Function<T,R>, DoubleFunction<R>, IntFunction<R> и LongFunction<R>?
Function<T, R> - интерфейс, с помощью которого реализуется функция, получающая на вход экземпляр класса T и возвращающая на выходе экземпляр класса R.
Методы по умолчанию могут использоваться для построения цепочек вызовов (compose, andThen).
Function<String, Integer> toInteger = Integer::valueOf;
Function<String, String> backToString = toInteger.andThen(String::valueOf);
backToString.apply("123"); // "123"
DoubleFunction<R> - функция получающая на вход Double и возвращающая на выходе экземпляр класса R;
IntFunction<R> - функция получающая на вход Integer и возвращающая на выходе экземпляр класса R;
LongFunction<R> - функция получающая на вход Long и возвращающая на выходе экземпляр класса R.
Для чего нужны функциональные интерфейсы UnaryOperator<T>, DoubleUnaryOperator, IntUnaryOperator и LongUnaryOperator?
UnaryOperator<T> (унарный оператор) принимает в качестве параметра объект типа T, выполняет над ними операции и возвращает результат операций в виде объекта типа T:
UnaryOperator<Integer> operator = x -> x * x;
System.out.println(operator.apply(5)); // 25
DoubleUnaryOperator - унарный оператор получающий на вход Double;
IntUnaryOperator - унарный оператор получающий на вход Integer;
LongUnaryOperator - унарный оператор получающий на вход Long.
Для чего нужны функциональные интерфейсы BinaryOperator<T>, DoubleBinaryOperator, IntBinaryOperator и LongBinaryOperator?
BinaryOperator<T> (бинарный оператор) - интерфейс, с помощью которого реализуется функция, получающая на вход два экземпляра класса T и возвращающая на выходе экземпляр класса T.
BinaryOperator<Integer> operator = (a, b) -> a + b;
System.out.println(operator.apply(1, 2)); // 3
DoubleBinaryOperator - бинарный оператор получающий на вход Double;
IntBinaryOperator - бинарный оператор получающий на вход Integer;
LongBinaryOperator - бинарный оператор получающий на вход Long.
Для чего нужны функциональные интерфейсы Predicate<T>, DoublePredicate, IntPredicate и LongPredicate?
Predicate<T> (предикат) - интерфейс, с помощью которого реализуется функция, получающая на вход экземпляр класса T и возвращающая на выходе значение типа boolean.
Интерфейс содержит различные методы по умолчанию, позволяющие строить сложные условия (and, or, negate).
Predicate<String> predicate = (s) -> s.length() > 0;
predicate.test("foo"); // true
predicate.negate().test("foo"); // false
DoublePredicate - предикат получающий на вход Double;
IntPredicate - предикат получающий на вход Integer;
LongPredicate - предикат получающий на вход Long.
Для чего нужны функциональные интерфейсы Consumer<T>, DoubleConsumer, IntConsumer и LongConsumer?
Consumer<T> (потребитель) - интерфейс, с помощью которого реализуется функция, которая получает на вход экземпляр класса T, производит с ним некоторое действие и ничего не возвращает.
Consumer<String> hello = (name) -> System.out.println("Hello, " + name);
hello.accept("world");
DoubleConsumer - потребитель получающий на вход Double;
IntConsumer - потребитель получающий на вход Integer;
LongConsumer - потребитель получающий на вход Long.
Для чего нужны функциональные интерфейсы Supplier<T>, BooleanSupplier, DoubleSupplier, IntSupplier и LongSupplier?
Supplier<T> (поставщик) - интерфейс, с помощью которого реализуется функция, ничего не принимающая на вход, но возвращающая на выход результат класса T;
Supplier<LocalDateTime> now = LocalDateTime::now;
now.get();
DoubleSupplier - поставщик возвращающий Double;
IntSupplier - поставщик возвращающий Integer;
LongSupplier - поставщик возвращающий Long.
Для чего нужен функциональный интерфейс BiConsumer<T,U>?
BiConsumer<T,U> представляет собой операцию, которая принимает два аргумента классов T и U производит с ними некоторое действие и ничего не возвращает.
Для чего нужен функциональный интерфейс BiFunction<T,U,R>?
BiFunction<T,U,R> представляет собой операцию, которая принимает два аргумента классов T и U и возвращающая результат класса R.
Для чего нужен функциональный интерфейс BiPredicate<T,U>?
BiPredicate<T,U> представляет собой операцию, которая принимает два аргумента классов T и U и возвращающая результат типа boolean.