Как да започнем да работим с Lambda Expressions в Java

Преди да бъде добавена поддръжка на ламбда изрази от JDK 8, използвах само примери за тях на езици като C # и C ++.

След като тази функция беше добавена към Java, започнах да ги разглеждам малко по-отблизо.

Добавянето на ламбда изрази добавя елементи на синтаксис, които увеличават изразителната сила на Java. В тази статия искам да се съсредоточа върху основни концепции, с които трябва да се запознаете, за да можете да започнете да добавяте ламбда изрази към кода си днес.

Бързо въведение

Ламбда изразите се възползват от възможностите на паралелния процес на многоядрените среди, както се вижда с подкрепата на тръбопроводни операции с данни в Stream API.

Те са анонимни методи (методи без имена), използвани за реализиране на метод, дефиниран от функционален интерфейс. Важно е да знаете какво представлява функционалният интерфейс, преди да си изцапате ръцете с ламбда изрази.

Функционален интерфейс

Функционалният интерфейс е интерфейс, който съдържа един и само един абстрактен метод.

Ако погледнете в определението на интерфейса на Java стандарт Изпълнима, ще забележите как тя попада в определението за функционален интерфейс, защото тя определя само един метод: 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 + "!";

Блокиране на ламбда изрази

Досега съм обхванал проби от ламбда с един израз. Има друг тип израз, който се използва, когато кодът от дясната страна на оператора със стрелка съдържа повече от един израз, известен като блок lambdas :

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.