
Mielőtt a JDK 8 hozzáadta a Lambda kifejezések támogatását, csak példákat használtam rájuk olyan nyelveken, mint a C # és a C ++.
Miután ezt a funkciót hozzáadtuk a Java-hoz, egy kicsit közelebbről elkezdtem vizsgálni őket.
A lambda kifejezések hozzáadása olyan szintaxis elemeket ad hozzá, amelyek növelik a Java kifejezőerejét. Ebben a cikkben azokra az alapfogalmakra szeretnék összpontosítani, amelyeket meg kell ismernie, hogy ma elkezdhesse a lambda kifejezések hozzáadását a kódjához.
Gyors bevezetés
A Lambda kifejezések kihasználják a többmagos környezetek párhuzamos folyamatlehetőségeit, amint azt a Stream API adatainak csővezeték-műveleteinek támogatása is szemlélteti.
Névtelen módszerek (név nélküli módszerek), amelyeket egy funkcionális interfész által meghatározott módszer megvalósítására használnak. Fontos tudni, hogy mi a funkcionális felület, mielőtt a kezét bepiszkítaná a lambda kifejezésekkel.
Funkcionális felület
A funkcionális interfész olyan felület, amely egyetlen és egyetlen elvont módszert tartalmaz.
Ha megnézzük a meghatározása a Java szabvány futtatható felületen, akkor észre, hogy beleesik a meghatározását funkcionális felület, mert ez csak definiálja egy módszer: run()
.
Az alábbi kódmintában a módszer computeName
implicit módon absztrakt, és ez az egyetlen módszer, amely a MyName-t funkcionális interfésszé teszi.
interface MyName{ String computeName(String str); }
A nyíl operátor
A Lambda kifejezések bevezetik az új nyíl operátort ->
a Java-ba. Két részre osztja a lambda kifejezéseket:
(n) -> n*n
A bal oldal adja meg a kifejezés által megkövetelt paramétereket, amelyek üresek is lehetnek, ha nincs szükség paraméterekre.
A jobb oldal a lambda test, amely meghatározza a lambda kifejezés működését. Hasznos lehet úgy gondolni erre az operátorra, mint „válik”. Például: „n n = n lesz”, vagy „n n lesz négyzet”.
A funkcionális felület és a nyíl operátor koncepcióit szem előtt tartva összeállíthat egy egyszerű lambda kifejezést:
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")); }
A fenti mintában található változók morningGreeting
és a eveningGreeting
6. és 7. sor hivatkoznak az MyGreeting
interfészre, és meghatározzák a különböző üdvözlő kifejezéseket.
A lambda kifejezés megírásakor az is lehetséges, hogy a kifejezésben pontosan megadjuk a paraméter típusát:
MyGreeting morningGreeting = (String str) -> "Good Morning " + str + "!"; MyGreeting eveningGreeting = (String str) -> "Good Evening " + str + "!";
Blokkolja a Lambda kifejezéseket
Eddig egyetlen expressziós lambdas mintákat fedtem le. Van egy másik típusú kifejezés, amelyet akkor használnak, amikor a nyíl operátor jobb oldalán lévő kód egynél több utasítást tartalmaz, lambda blokk néven :
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")); }
Általános funkcionális interfészek
A lambda kifejezés nem lehet általános. De a lambda kifejezéshez tartozó funkcionális interfész képes. Lehetőség van egy általános felület megírására és a különböző visszatérési típusok kezelésére, mint ez:
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)); }
Lambda kifejezések mint érvek
A lambdas egyik általános használata, hogy érvként adja át őket.
Bármely kóddarabban felhasználhatók, amely megadja a céltípust. Ezt izgalmasnak találom, mivel ez lehetővé teszi számomra, hogy a futtatható kódot argumentumként átadjam a módszereknek.
A lambda kifejezések paraméterként történő továbbításához csak ellenőrizze, hogy a funkcionális interfész típusa kompatibilis-e a szükséges paraméterrel.
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")); }
Ezek a fogalmak jó alapot nyújtanak a lambda kifejezésekkel való munka megkezdéséhez. Vessen egy pillantást a kódjára, és nézze meg, hol növelheti a Java kifejező erejét.