Выражения Java Lambda - это новая функция, представленная Java 8. Можно сказать, что они являются синтаксическим сахаром для моделируемого функционального программирования. Они похожи на закрытие в JavaScript, но они несколько разные. Основная цель состоит в том, чтобы обеспечить функциональный синтаксис для упрощения нашего кодирования.
Lambda Basic Syntax
Основная структура Lambda -это (аргументы) -> тело, и есть несколько ситуаций:
Тело должно включать операторы с {}, а {} может быть опущено, когда есть только одно утверждение.
Общие методы письма следующие:
(а) -> a * a
(int a, int b) -> a + b
(a, b) -> {return a - b;}
() -> System.out.println (thread.currentThread (). GetId ())
Функциональный интерфейс
концепция
Выражения Java Lambda основаны на функциональных интерфейсах. Что такое функциональный интерфейс? Проще говоря, это интерфейс только с одним методом (функцией). Цель этого типа интерфейса - одна операция, которая эквивалентна одной функции. Общие интерфейсы, такие как бегство и компаратор, являются функциональными интерфейсами и аннотируются @functionalInterface.
Привести пример
В качестве примера легко понять, используя поток. Занимаемый интерфейс представляет собой интерфейс, обычно используемый при программировании потока, который включает в себя метод void run (), который является логикой выполнения потока. Согласно предыдущему синтаксису, мы обычно используем выполняемый анонимный класс для создания новых потоков следующим образом:
новый поток (new Runnable () {@Override public void run () {System.out.println (thread.currentThread (). getId ());}}). start ();Если вы пишете слишком много, разве это не скучно? Правила письма, основанные на лямбде, становятся кратким и ясным, следующим образом:
New Thread (() -> System.out.println (Thread.currentThread (). getId ())). start ();
Обратите внимание на параметры потока. Анонимная реализация Runnable реализована в одном предложении, и она написана как следующее, чтобы лучше понять.
Runnable r = () -> system.out.println (thread.currentthread (). GetId ());
новый поток (r) .start ();
Конечно, цель Ламбды-не только писать кратко, но и суммировать цель более высокого уровня после ее понимания.
Давайте посмотрим на другой пример компаратора. Согласно традиционному методу письма, следующим образом:
Integer [] a = {1, 8, 3, 9, 2, 0, 5}; Arrays.sort (a, новый компаратор <Integer> () {@override public int compare (Integer o1, integer o2) {return o1 - o2;}});Выражения Lambda написаны следующим образом:
Integer [] a = {1, 8, 3, 9, 2, 0, 5};
Arrays.sort (a, (O1, O2) -> O1 - O2);
Функциональные интерфейсы в JDK
Чтобы существующая библиотека классов напрямую использовала выражения Lambda, в Java 8 были некоторые интерфейсы, которые были отмечены как функциональные интерфейсы:
Новый пакет java.util.function была добавлена в Java 8, в результате чего обычно используемый функциональный интерфейс:
Кроме того, более конкретные функции добавляются к обработке основных типов, в том числе: Booleansupplier, DoubleBinaryoperator, DoubleConsumer, DoubleFunction <r>, двойное предвыкание, Double -Sopplier, DoubletointFunction, DoubleTolongFunction, Doubletolongfunction, DoubleUnaryoperator, Intconisurator, Intconsumer, <R, R -r, R -r, R -r, r, R -r, R -r. IntSupplier, IntToDoubleFunction, IntToLongFunction, IntUnaryOperator, LongBinaryOperator, LongConsumer,LongFunction<R>, LongPredicate, LongSupplier, LongToDoubleFunction,LongToIntFunction, LongUnaryOperator, ToDoubleBiFunction<T, U>, ToDoubleFunction<T>,ToIntBiFunction<T, U>, Tointfunction <t>, tolongbifunction <t, u>, tolongfunction <t>. В сочетании с вышеуказанными функциональными интерфейсами вы можете увидеть роль интерфейса с первого взгляда через название класса этих основных функциональных интерфейсов.
Создать функциональный интерфейс
Иногда нам нужно самостоятельно реализовать функциональный интерфейс, и метод очень прост. Сначала вы должны убедиться, что этот интерфейс может иметь только одну операцию функции, а затем аннотировать @functionalInterface на типе интерфейса.
Тип вывод
Вывод типа является основой выражений Lambda, а процесс вывода типа является процесс компиляции выражений Lambda. Следующий код является примером:
Функция <string, integer> strtoint = str -> integer.parseint (str);
Во время компиляции процесс деривации типа, который я понимаю, заключается в следующем:
Целевой тип здесь является ключом, и подпись метода получается через тип цели, а затем сравнивает его с выражением Lambda.
Ссылка на метод
Основой ссылки на метод (ссылка на метод) также является функциональным интерфейсом, который может быть непосредственно реализован в качестве функционального интерфейса, имеет ту же функцию, что и Lambda Expressions, а также зависит от деривации типа. Ссылки на методы можно рассматривать как упрощение выражений Lambda, которые называют только один метод.
Синтаксис, на который ссылаются метод: type :: Methodname или Instancename :: Methodname, а метод, соответствующий конструктору, является новым.
Например, примеры были использованы выше:
Функция <string, integer> strtoint = str -> integer.parseint (str);
Соответствующая ссылка на метод
Функция <string, integer> strtoint = integer :: parseint;
В соответствии с типом метода, ссылки на методы в основном разделены на следующие типы: Ссылка на метод конструктора, статический метод, ссылка на метод экземпляра на экземпляре, ссылку на метод экземпляра на тип и т. Д.
Справочник по методу конструктора
Синтаксис: type :: new. Например, следующая функция состоит в том, чтобы преобразовать строку в массив
Справочный состав метода
Функция <string, integer> strtoint = integer :: new;
Lambda писать
Функция <string, integer> strtoint = str -> new Integer (str);
Традиционное письмо
Function <string, integer> strtoint = new Function <String, Integer> () {@Override public integer Apply (String str) {return new Integer (str); }};
Справочник по конструктору массива
Синтаксис: type [] :: new. Например, следующая функция заключается в создании строкового массива указанной длины
Справочный состав метода
Function <Integer, String []> fixerArray = string [] :: new;
Справочный состав метода
Function <Integer, String []> fixedArray = Length -> New String [Length];
Традиционное письмо
Function <Integer, String []> FILTARARRAY = NEW FUNCTION <Integer, String []> () {@Override public String [] Apply (Integer Length) {return new String [length]; }};Статический метод ссылка
Синтаксис: type :: new. Поскольку следующая функция также используется для преобразования строк в массивы
Справочный состав метода
Функция <string, integer> strtoint = integer :: parseint;
Lambda писать
Функция <string, integer> strtoint = str -> integer.parseint (str);
Традиционное письмо
Function <string, integer> strtoint = new Function <String, Integer> () {@Override public integer Apply (String str) {return integer.parseint (str); }};Ссылка на метод экземпляра на экземпляре
Синтаксис: instancename :: Methodname. Например, следующая функция суждения используется для определения того, существует ли заданное имя в списке
Список <string> names = arrays.aslist (new String [] {"Zhang San", "li Si", "wang wu"});
Predicate <string> CheckNameExists = names :: Содержит;
System.out.println (CheckNameExists.test ("Zhang San"));
System.out.println (CheckNameExists.test ("Zhang Si"));
Ссылка на метод экземпляра на тип
Синтаксис: type :: methodname. Ссылка на время выполнения относится к объекту в контексте, такой как функция ниже, чтобы вернуть длину строки
Function <string, integer> calcstrength = string :: length; system.out.println (calcstrength.apply ("Zhang San")); List <string> names = arrays.aslist (new String [] {"Zhangsan", "lisi", "wangwu"}); names.stream ().
Например, следующая функция указала сепаратор для разделения строки на массив
Bifunction <string, string, string []> split = string :: split;
String [] names = split.apply ("Zhangsan, Lisi, Wangwu", ",");
System.out.println (Arrays.tostring (names));
Потоковые объекты
концепция
Что такое поток? Поток здесь отличается от inputstream и outputstream в io. Поток расположен в пакете java.util.stream, а также недавно добавлен в Java 8. Stream - это лишь набор элементов, которые поддерживают последовательные операции параллельной агрегации, которые можно понимать как улучшенную версию коллекции или итератора. Что такое операция агрегации? Чтобы привести простой пример, общие включают средний, максимальный, минимум, сумма, сортировка, фильтрация и т. Д.
Несколько функций потока:
Единая обработка. После завершения одной обработки текущий поток закрыт.
Поддерживать общие способы получить потоки в параллельных операциях
Получить из коллекции
Collection.stream ();
Collection.parallelstream ();
Статическая фабрика
Arrays.stream (массив)
Stream.of (t…)
Intstream.range ()
Здесь мы только дадим краткое введение в потоку, и ниже будет конкретные приложения. Если вы хотите поговорить о отношениях между потоком и выражениями Lambda, на самом деле нет особенно близких отношений. Это просто то, что Lambda выражения значительно облегчают использование потока. Без выражений Lambda большое количество анонимных классов будет генерироваться при использовании потока, что очень неловко.
Привести пример
Следующие демонстрации зависят от объекта сотрудника и объекта списка, состоящего из объекта сотрудника.
Сотрудник открытого класса {частное название строки; частный строковый секс; частный int возраст; Public Employee (название строки, строковое секс, int age) {super (); this.name = name; this.sex = sex; this.age = возраст; } public String getName () {return name; } public String getSex () {return Sex; } public int getage () {return Age; } @Override public String toString () {StringBuilder Builder = new StringBuilder (); builder.append ("Сотрудник {name ="). Append (name) .append (", sex ="). Append (sex) .append (", age ="). Append (age) .append ("}"); return Builder.toString (); }} List <Сотрудник> сотрудники = new ArrayList <> (); Сотрудники. Адд (новый сотрудник ("Zhang San", "Male", 25)); Сотрудники. Адд (новый сотрудник ("li si", "Женщина", 24)); Сотрудники. Адд (новый сотрудник («Wang Wu», «Женщина», 23); сотрудники. Адд (новый сотрудник («суббота», «мужчина», 22)); работники. Адд (новый сотрудник («Солнечный ци», «Женщина», 21); работники. Адд (новый сотрудник («Liu Ba», «Мужчина», 20));Распечатайте все сотрудники
Коллекция предоставляет для нас метод Foreach для управления отдельными объектами один за другим.
сотрудники.foreach (e -> system.out.println (e));
или
сотрудники.
Сортировка по возрасту
Collections.sort (сотрудники, (E1, E2) -> e1.getage () - e2.getage ());
сотрудники.foreach (e -> system.out.println (e));
или
сотрудники.
Распечатайте самую старую женщину
Макс/мин возвращает самый большой элемент/мин в указанных условиях сортировки
Сотрудник MAXAGEFEMALEEMPLOOKEE = сотрудники.
Распечатайте сотрудников мужского пола старше 20 лет
Отфильтровать элементы, которые соответствуют критериям
Сотрудники.stream ()
.filter (e -> e.getage ()> 20 && "male" .equals (e.getSex ())))
.foreach (e -> System.out.println (e));
Распечатайте двух самых старых сотрудников мужского пола
Ограниченный метод перехватывает ограниченные элементы
сотрудники.
Распечатайте имена всех сотрудников мужского пола, использовать, отделить
Карта, чтобы сформировать новый поток после выполнения заданной функции.
String maleemployeesnames = сотрудники.
Статистическая информация
IntsummaryStatistics, DoubleMmaryStatistics, LongsummaryStatistics содержит сводные данные в потоке.
Intsummarystatistics stat = сотрудники. stat.getMin ()); System.out.println («Средний возраст:» + stat.getAverage ());
Суммировать
Выражения Lambda действительно могут снизить много кода и повысить производительность. Конечно, есть недостатки, то есть сложные выражения будут плохо читаемыми, или это может быть потому, что они не очень привыкли к этому. Если вы привыкнете к этому, я полагаю, что вам это понравится. У всего есть две стороны, это зависит от того, как мы уравновешиваем плюсы и минусы, особенно в команде.
Выше приведено информация, разбирающая Java8 Javalambda. Мы будем продолжать добавлять соответствующую информацию в будущем. Спасибо за поддержку этого сайта!