
До того, як підтримку виразів Лямбда додав JDK 8, я використовував лише їх приклади на таких мовах, як C # та C ++.
Коли цю функцію було додано до Java, я почав розглядати їх трохи ближче.
Додавання лямбда-виразів додає елементи синтаксису, що збільшують виражальну силу Java. У цій статті я хочу зосередитись на основних концепціях, з якими вам потрібно ознайомитись, щоб сьогодні ви могли почати додавати лямбда-вирази до свого коду.
Швидкий вступ
Лямбда-вирази використовують переваги можливостей паралельних процесів багатоядерних середовищ, як це видно за підтримки конвеєрних операцій з даними в потоковому API.
Це анонімні методи (методи без імен), що використовуються для реалізації методу, визначеного функціональним інтерфейсом. Важливо знати, що таке функціональний інтерфейс, перш ніж забруднювати руки лямбда-виразами.
Функціональний інтерфейс
Функціональний інтерфейс - це інтерфейс, який містить один і лише один абстрактний метод.
Якщо ви подивіться на визначення інтерфейсу Java стандарт Runnable, ви помітите , як він потрапляє в визначення функціонального інтерфейсу , оскільки він визначає тільки один метод: run()
.
У наведеному нижче прикладі коду метод computeName
є неявно абстрактним і є єдиним методом, визначеним, що робить MyName функціональним інтерфейсом.
interface MyName{ String computeName(String str); }
Оператор стрілки
Лямбда-вирази вводять новий оператор стрілки ->
в Java. Він ділить лямбда-вирази на дві частини:
(n) -> n*n
Ліва сторона вказує параметри, необхідні для виразу, які також можуть бути порожніми, якщо параметри не потрібні.
Права сторона - це лямбда-тіло, яке визначає дії лямбда-виразу. Можливо, було б корисно думати про цей оператор як “стає”. Наприклад, "n стає n * n", або "n стає n квадратом".
Маючи на увазі концепції функціонального інтерфейсу та оператора стрілки, ви можете скласти простий лямбда-вираз:
interface NumericTest { boolean computeTest(int n); } public static void main(String args[]) { NumericTest isEven = (n) -> (n % 2) == 0; NumericTest isNegative = (n) -> (n < 0); // Output: false System.out.println(isEven.computeTest(5)); // Output: true System.out.println(isNegative.computeTest(-5)); }
interface MyGreeting { String processName(String str); } public static void main(String args[]) { MyGreeting morningGreeting = (str) -> "Good Morning " + str + "!"; MyGreeting eveningGreeting = (str) -> "Good Evening " + str + "!"; // Output: Good Morning Luis! System.out.println(morningGreeting.processName("Luis")); // Output: Good Evening Jessica! System.out.println(eveningGreeting.processName("Jessica")); }
Змінні morningGreeting
та eveningGreeting
рядки 6 та 7 у зразку вище посилаються на MyGreeting
інтерфейс та визначають різні вирази привітання.
Під час написання лямбда-виразу також можна явно вказати тип параметра у виразі так:
MyGreeting morningGreeting = (String str) -> "Good Morning " + str + "!"; MyGreeting eveningGreeting = (String str) -> "Good Evening " + str + "!";
Блокувати лямбда-вирази
Наразі я охопив зразки лямбд з одним виразом. Існує інший тип виразу, який використовується, коли код праворуч від оператора стрілки містить більше одного виразу, відомого як блок лямбди :
interface MyString { String myStringFunction(String str); } public static void main (String args[]) { // Block lambda to reverse string MyString reverseStr = (str) -> { String result = ""; for(int i = str.length()-1; i >= 0; i--) result += str.charAt(i); return result; }; // Output: omeD adbmaL System.out.println(reverseStr.myStringFunction("Lambda Demo")); }
Загальні функціональні інтерфейси
Лямбда-вираз не може бути загальним. Але функціональний інтерфейс, пов'язаний з лямбда-виразом, може. Можна написати один загальний інтерфейс і обробляти різні типи повернення, як це:
interface MyGeneric { T compute(T t); } public static void main(String args[]){ // String version of MyGenericInteface MyGeneric reverse = (str) -> { String result = ""; for(int i = str.length()-1; i >= 0; i--) result += str.charAt(i); return result; }; // Integer version of MyGeneric MyGeneric factorial = (Integer n) -> { int result = 1; for(int i=1; i <= n; i++) result = i * result; return result; }; // Output: omeD adbmaL System.out.println(reverse.compute("Lambda Demo")); // Output: 120 System.out.println(factorial.compute(5)); }
Лямбда-вирази як аргументи
Одним із поширених видів використання лямбд є передача їх як аргументів.
Вони можуть бути використані в будь-якому фрагменті коду, який забезпечує цільовий тип. Я вважаю це захоплюючим, оскільки це дозволяє мені передавати виконуваний код як аргументи методам.
Щоб передавати лямбда-вирази як параметри, просто переконайтесь, що функціональний тип інтерфейсу сумісний з необхідним параметром.
interface MyString { String myStringFunction(String str); } public static String reverseStr(MyString reverse, String str){ return reverse.myStringFunction(str); } public static void main (String args[]) { // Block lambda to reverse string MyString reverse = (str) -> { String result = ""; for(int i = str.length()-1; i >= 0; i--) result += str.charAt(i); return result; }; // Output: omeD adbmaL System.out.println(reverseStr(reverse, "Lambda Demo")); }
Ці концепції дадуть вам добру основу для початку роботи з лямбда-виразами. Погляньте на свій код і подивіться, де ви можете збільшити виразну силу Java.