В первый раз, когда я подвергался воздействию Lambda Expressions в TypeScript (Superset of JavaScript), и он должен был сделать метод TypeScript за пределами этого метода, а не в этом методе. После его использования я вдруг понял, что Lambda не является новой особенностью JDK8? Поэтому я чувствовал, что проверил соответствующую информацию и записал ее:
1. Параметризация поведения
Короче говоря, параметризация поведения означает, что тело функции содержит только общий код, похожий на шаблон, в то время как некоторая логика, которая меняется с бизнес-сценарием, передается в функцию в форме параметров. Использование параметризации поведения может сделать программу более общей, чтобы справиться с потребностями частых изменений.
Рассмотрим бизнес -сценарий, предполагая, что нам нужно отфильтровать Apple через программу, мы сначала определяем сущность Apple:
открытый класс Apple {/** номер*/private long id;/** color*/private color color;/** вес*/private float weight;/** Origin*/private String Origin; public apple () {} public apple (long id, цвет, вес поплавки, строка происхождение) {this.id = id; this.color = color; this.wewse = this.origin = origin;Первоначальным спросом пользователей может быть просто отфильтровать зеленые яблоки через программу, чтобы мы могли быстро реализовать их через программу:
Общедоступный статический список <pple> FilterGreenApples (List <pple> Apples) {list <pple> FilterApples = new ArrayList <> (); для (Final Apple Apple: Apples) {if (color.green.equals (apple.getColor ())) {filterApples.Add (Apple);} return FilterApples;Этот код прост и ничего не стоит сказать. Но когда пользователь нуждается в зеленых, кажется, что изменение кода проста, это не что иное, как изменение зеленого состояния суждения на красный. Но нам нужно рассмотреть еще одну проблему. Если изменяющиеся условия часто меняются, это делается? Если это просто изменение цвета, то мы можем напрямую позволить пользователю пройти в условиях цветового суждения, и параметры метода суждения изменяют «набор, который должен быть оценен, и цвет для фильтрации». Но что, если пользователь не только судит цвет, но и хочет судить вес, размер и т. Д.? Как вы думаете, мы можем просто добавить разные параметры, чтобы завершить решение? Но действительно ли хорошо передать такие параметры? Если существует все больше и больше условий фильтрации, и режим комбинации становится все более и более сложным, необходимо ли нам рассматривать все ситуации и иметь соответствующие стратегии преодоления для каждой ситуации? В настоящее время мы можем параметризировать поведение, извлечь условия фильтрации и передавать их в виде параметров. В настоящее время мы можем инкапсулировать интерфейс суждения:
public interface AppleFilter {/*** Filter abstract** @param apple* @return*/boolean accept(Apple apple);}/*** Encapsulate filters into interface** @param apples* @param filter* @return*/public static List<Apple> filterApplesByAppleFilter(List<Apple> apples, AppleFilter filter) {List<Apple> filterApples = new ArrayList<>(); Для (Final Apple Apple: Apples) {if (filter.accept (Apple)) {filterApples.Add (Apple);}} return FilterApples;}После приведенной выше абстракции поведения мы можем установить условия фильтра в конкретном вызове и передавать условия в качестве параметров в метод. В настоящее время мы используем метод анонимного внутреннего класса:
public static void main (string [] args) {list <pple> apples = new ArrayList <> (); // Filter apple list <pple> filterapples = filterapplesBypplefilter (яблоки, новые Applefilter () {@OverridePublic Booleance Accept (Apple) {// Filter Red Apples с весом больше, чем 100 -й. Apple.getWeew -Weight ()> 100;}});}Этот дизайн часто используется в JDK, такой как java.util.comparator, java.util.concurrent.callable и т. Д. При использовании этого типа интерфейса мы можем использовать анонимные классы для указания конкретной логики выполнения функции в конкретных местах вызова. Однако из приведенного выше блока кода, хотя он очень гик, он не достаточно краткий. В Java8 мы можем упростить его через лямбду:
// Филтровать список Apple <pple> FilterApples = filterApplesByppleFilter (Apples, (Apple Apple) -> color.red.Equals (Apple.getColor ()) && apple.getweew -weight ()> = 100); // () -> xxx () -параметры метода, а XXX реализация метода -метод реализация метода.
2. Определение выражения выражения Lambda
Мы можем определить выражение лямбды как краткую и сносную анонимную функцию. Прежде всего, нам нужно прояснить, что выражение лямбды по сути является функцией. Хотя он не принадлежит конкретному классу, он имеет список параметров, корпус функции, тип возврата и возможность бросить исключения; Во -вторых, это анонимно, а выражение лямбда не имеет определенного имени функции; Выражение Lambda может быть передано как параметры, тем самым значительно упрощает написание кода. Определение формата заключается в следующем:
Формат 1: Список параметров -> выражение
Формат 2: Список параметров -> {коллекция выражения}
Следует отметить, что выражение лямбда подразумевает ключевое слово возврата, поэтому в одном выражении нам не нужно явно писать ключевое слово возврата, но когда выражение является набором утверждений, нам нужно явно добавлять возврат и приложить несколько выражений с помощью вьющихся скобок {}. Давайте посмотрим несколько примеров ниже:
// Возвращение длины заданной строки, неявно возвращаемого оператора (String S) -> s.length () // Всегда возвращайте независимый метод () () -> 42 // Содержит несколько строк выражения, заключенные в Curly Brace (int x, int y) -> {int z = x * y; return x + z;}3. Используйте Lambda Expressions на основе функциональных интерфейсов
Использование выражений Lambda требует помощи функциональных интерфейсов, что означает, что только тогда, когда появляется функциональный интерфейс, мы можем упростить их с помощью Lambda Expressions.
Пользовательский функциональный интерфейс:
Функциональные интерфейсы определяются как интерфейсы, которые имеют только один абстрактный метод. Улучшение в определении интерфейса Java8 заключается в внедрении методов по умолчанию, чтобы мы могли предоставить реализации методов по умолчанию в интерфейсе. Однако, независимо от того, сколько методов по умолчанию существует, если у него есть только один абстрактный метод, это функциональный интерфейс, следующим образом (см. Вышеуказанный Applefilter):
/*** Интерфейс Apple Filter*/ @functionalInterfacepublic interface applefilter {/*** Условие фильтра Аннотация ** @param apple* @return*/boolean access (Apple Apple);}Applefilter содержит только абстрактный метод принять (Apple Apple). Согласно определению, его можно рассматривать как функциональный интерфейс. При определении мы добавляем аннотацию @functionalInterface в интерфейс, чтобы отметить интерфейс как функциональный интерфейс. Однако этот интерфейс не является обязательным. После добавления этого интерфейса компилятор ограничивает интерфейс только для абстрактного метода, в противном случае сообщается об ошибке, поэтому рекомендуется добавить эту аннотацию в функциональный интерфейс.
JDK поставляется с функциональным интерфейсом:
JDK - это выражение Lambda с богатыми функциональными интерфейсами. Ниже приведены примеры использования предиката <T>, потребителя <t>, функции <t, r> соответственно.
ПРЕДУПРЕЖДЕНИЕ:
@FunctionalInterfacepubbublic Interface Predicate <t> {/*** Оценивает этот прогноз по данному аргументу. ** @param t Входной аргумент* @return {@code true} Если ввод аргумент соответствует прогнозу,* в противном случае {@code false}*/boolean (t);};Функция предиката аналогична Applefilter выше. Он использует условия, которые мы устанавливаем снаружи, чтобы проверить входящие параметры, и возвращает логический результат проверки. Следующее использует предикат для фильтрации элементов коллекции списков:
/**** @param List* @param Predicate* @param <t>* @return*/public <t> list <t> filter (list <t> list, predicate <t> предикат) {list <t> newlist = new ArrayList <t> (); for (final t: list) {if (predicate.test (t)) {newlist.add (t);использовать:
demo.filter (list, (string str) -> null! = str &&! str.isempty ());
Потребитель
@FunctionalInterfacePublic Interface Consumer <t> {/*** выполняет эту операцию в данном аргументе. ** @param t Входной аргумент*/void Accept (t t);}Потребитель предоставляет абстрактную функцию принятия, которая получает параметры, но не возвращает значения. Следующее использует потребителя для прохождения коллекции.
/*** Обращение к коллекции и выполните пользовательское поведение ** @param List* @param Consumer* @param <t>*/public <t> void filter (список <t> list, потребитель <t> потребитель) {for (final t t: list) {contivemer.accep (t);}}}}Используя вышеуказанный функциональный интерфейс, перечислите через коллекцию строк и печатайте непустые строки:
demo.filter (list, (string str) -> {if (stringutils.isnotblank (str)) {System.out.println (str);}});Функция
@FunctionalInterfacepubbublic function function <t, r> {/*** применяет эту функцию к данному аргументу. ** @param t Аргумент функции*@return Результат функции*/r Apply (t t);}Функция выполняет операцию преобразования. Вход - это данные типа T и возвращает данные типа R. В следующей функции используется функция для конвертации набора:
public <T, r> list <r> Filter (list <t> list, function <t, r> function) {list <r> newlist = new ArrayList <r> (); for (final t t: list) {newlist.add (function.apply (t));} return newlist;}другой:
demo.filter (list, (string str) -> integer.parseint (str));
Приведенные выше функциональные интерфейсы также предоставляют некоторые реализации логических операций по умолчанию. Давайте поговорим об этом позже, введя методы интерфейса Java8 по умолчанию ~
Некоторые вещи, на которые следует обратить внимание во время использования:
Вывод типа:
Во время процесса кодирования иногда мы можем задаться вопросом, какой функциональный интерфейс будет соответствовать нашему вызовому коду. Фактически, компилятор вынесет правильные суждения на основе параметров, типа возврата, типа исключения (если присутствует) и т. Д.
При вызове определенным образом тип параметра может быть опущен в несколько раз, тем самым еще раз упрощая код:
// Фильтровать список Apple <pple> FilterApples = FilterApplesByppleFilter (яблоки, (Apple Apple) -> color.red.Equals (apple.getColor ()) && apple.getweight ()> = 100); // В некоторых случаях мы можем даже пропустить типы параметров, и компилятор будет корректировать списки <pple> filterApples = filterapplesByplefiltersbypliters -applypliters -appliters -applypliters -applypliters -applypliters -applypliter -applyplefliters -applypliter -applypliters -applypliter -applyplef Color.red.Equals (apple.getColor ()) && apple.getweight ()> = 100);
Местные переменные
Все примеры выше наших выражений Lambda используют их параметры тела, мы также можем использовать локальные переменные в Lambda, следующим образом
int Weews = 100; List <plape> FilterApples = FilterApplesByppleFilter (яблоки, Apple -> color.red.equals (apple.getColor ()) && apple.getweight ()> = Вес) ;:
В этом примере мы используем локальный вес переменной в Lambda. Однако использование локальных переменных в лямбде должно потребовать, чтобы переменная была явно объявлена как окончательная или фактически окончательная. Это происходит главным образом потому, что локальная переменная хранится в стеке, а выражение лямбды запускается в другом потоке. Когда представление потока обращается к локальной переменной, переменная может быть изменена или переработана, поэтому после модификации с окончательной модификацией не будет проблем с безопасностью потока.
IV Метод цитата
Использование ссылок на метод может сделать код более упрощенным. Иногда это упрощение делает код более интуитивно понятным. Давайте посмотрим на пример:
/* ... Опустите операцию инициализации яблок* /// Использовать Lambda Expression Apples.sort ((Apple A, Apple B) -> float.compare (a.getweewewse (), b.getweew ())); // Использовать метод для обращения к Apples.sort (Comparator.comParing (Apple :: getWeewse));
Ссылки на метод подключить метод членства и метод самого через ::, в основном разделены на три категории:
Статический метод
(args) -> classname.staticmethod (args)
Преобразовать в
Classname :: staticmethod
Пример метода параметра
(args) -> args.instancemethod ()
Преобразовать в
Classname :: instancemethod // classname тип args
Метод внешнего экземпляра
(args) -> ext.instancemethod (args)
Преобразовать в
ext :: instancemethod (args)
См.
http://www.codeceo.com/article/lambda-of-java-8.html
Выше приведено выражение Lambda новой функции JDK8, которую редактор представил вам. Я надеюсь, что это будет полезно для вас. Если у вас есть какие -либо вопросы, пожалуйста, оставьте мне сообщение, и редактор ответит вам вовремя. Большое спасибо за вашу поддержку сайту wulin.com!