Эта статья участвовала в третьем треке "написание темы" тренировочного лагеря для создателей Nuggets. Подробнее см.:Dig Li Project | Идет третий этап тренировочного лагеря создателя, «написание» личного влияния.
В течение долгого времени Java был объектно-ориентированным языком, все является объектом, если вы хотите вызвать функцию, функция должна принадлежать классу или объекту, а затем использовать класс или объект для вызова. Но в других языках программирования, таких как js и c++, мы можем напрямую написать функцию и вызывать ее при необходимости, что можно назвать объектно-ориентированным программированием или функциональным программированием.
С функциональной точки зрения в объектно-ориентированном программировании нет ничего плохого, но с точки зрения разработки объектно-ориентированное программирование требует написания гораздо большего количества строк кода, которые могут повторяться. Например, при создании анонимного класса Runnable:
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("do something...");
}
};
Единственное, что действительно полезно в этом фрагменте кода, — это содержимое метода run, а остальное — структурные части языка программирования Java, бесполезные, но требующие написания.
К счастью, в Java 8 появились интерфейсы функционального программирования и лямбда-выражения, которые помогают нам.写更少更优雅的代码
// 一行即可
Runnable runnable = () -> System.out.println("do something...");
Функциональные интерфейсы
класс интерфейса只有一个
Абстрактный метод называется функциональным интерфейсом (Functional Interface), большая часть функционального интерфейса в JDK будет отмечена на@FunctionalInterface
Обратите внимание, что не все функциональные интерфейсы должны быть написаны@FunctionalInterface
Аннотация используется только для того, чтобы мы могли различать, какие интерфейсы являются функциональными.Конечно, если эта аннотация помечена, когда внутри есть несколько абстрактных методов, будет сообщено об ошибке компиляции.
Error:(3, 1) java: 意外的 @FunctionalInterface 注释
xxx 不是函数接口
在 接口 xxx 中找到多个非覆盖抽象方法
Когда класс является функциональным интерфейсом, мы можем напрямую использовать лямбда-выражения для его создания без написания большого количества шаблонного кода.
Письмо:
// 类名称 变量 = (参数) -> (函数体)
// 如
FunctionTest test = () -> { };
Встроенный функциональный интерфейс
Некоторые стандартные функциональные интерфейсы были встроены в JDK наjava.util.function
По упаковке он удовлетворяет нашим потребностям в большинстве случаев. Интерфейсы в пакете относительно общие.Если мы хотим написать новый функциональный интерфейс, мы можем сначала проверить, предоставлен ли уже пакет.
Итак, какие интерфейсы предоставляет этот пакет?
- Наиболее распространены четыре: Функция, Потребитель, Поставщик, Предикат. Стандартный ввод и вывод, рекомендуемый способ написания элегантного кода
- Функция: сценарий с одним входным параметром и одним выходным параметром.
- Потребитель: входной параметр, но не выходной параметр
- Поставщик: нет входного параметра, один выходной параметр
- Предикат: его можно рассматривать как специальную функцию, входной параметр, а выходной параметр имеет логический тип.
- Функциональный интерфейс с двумя входными параметрами, то есть два входных параметра и один выходной параметр.
BiFunction<T, U, R>
, наиболее типичным вариантом использования является метод Map в Java.- BiFunction: два входных параметра, один общий выходной параметр
- ToDoubleBiFunction, ToIntBiFunction, ToLongBiFunction. Два входных параметра, возвращающие выходной параметр исходного типа
HashMap<String, Object> map = new HashMap<>();
map.put("a",1);
map.put("b",2);
map.replaceAll((o, o2) -> o + o2.toString());
System.out.println(map.values())
-
Унарный функциональный интерфейс можно рассматривать как специальный функциональный интерфейс, а входные и выходные параметры имеют один и тот же тип. UnaryOperator, тот же тип преобразования.
-
Примитивные типы Функция, поскольку примитивные или первичные типы Java, int, short, double и т. д., не могут использоваться в качестве универсальных параметров. Официальные лица предоставляют специальные функциональные интерфейсы для этих примитивных типов.
- Тип Int: IntFunction, IntComsumer, IntSupplier, IntPredicate, IntToDoubleFunction, IntToLongFunction, IntUnaryOperator, ToIntFunction
официальный:
docs.Oracle.com/java-color/8/do…
Лямбда-выражения
Если вы понимаете функциональные интерфейсы, вы также в определенной степени понимаете лямбда-выражения.Лямбда-выражения эквивалентны использованию функциональных интерфейсов.Мы не можем просто писать интерфейсы, но и не использовать их.
Хотя Java поддерживает функциональные интерфейсы, функции Java по-прежнему должны быть помещены в классы и не могут существовать сами по себе, но поскольку функциональные интерфейсы имеют только одну абстрактную функцию, мы четко знаем, что нам нужно использовать метод. Таким образом, компилятор может автоматически помочь нам определить, какой метод использовать, без написания избыточного кода шаблона:
Runnable runnable = () -> System.out.println("do something...");
- Во-первых, Runnable — это функциональный интерфейс, поэтому мы можем использовать лямбда-выражения для его создания.
- Поскольку у метода run нет параметров, лямбда-выражение:(argument) -> {body}, параметр пустой
()
- Что касается тела функции, если у нас есть только одна строка кода, мы можем опустить {}.
В дополнение к лямбда-выражениям для вызовов функций существуют также некоторые операции со ссылками на методы, использующие::
, ссылаясь на метод или конструктор без фактического создания экземпляра объекта, вы можете исследовать
String::toUpperCase
System.out::println
"abc"::length
ArrayList::new
int[]::new
официальный:
Woohoo. Oracle.com/веб-папка/he…
docs.Oracle.com/Java Color/Picture О...
Наконец
Функциональное программирование на Java выходит далеко за рамки того, что здесь описано, и требует более подробного изучения. Конечно, это в основном знакомит с функциональным интерфейсом Java, который уже распространен в пакете java.util.function, и, наконец, дает краткое описание лямбда-выражений.
Справочный адрес:учебные пособия.Keane KO V.com/Java/lambda… Ууууу.Поставь арлингтон-терьера.com/java-8-lamb… Woohoo.поставь arlington terrier.com/java-8-func… docs.Oracle.com/java-color/8/do…