Lambda Expressionsin käytön aloittaminen Java-ohjelmassa

Ennen kuin JDK 8 lisäsi Lambda-lausekkeiden tuen, käytin niistä esimerkkejä vain kielillä, kuten C # ja C ++.

Kun tämä ominaisuus lisättiin Java-ohjelmaan, aloin tutkia niitä hieman lähempänä.

Lambda-lausekkeiden lisääminen lisää syntaksielementtejä, jotka lisäävät Java: n ilmaisuvoimaa. Tässä artikkelissa haluan keskittyä peruskäsitteisiin, jotka sinun on tunnettava, jotta voit aloittaa lambda-lausekkeiden lisäämisen koodiin tänään.

Pika esittely

Lambda-lausekkeet hyödyntävät moniydinympäristöjen rinnakkaisia ​​prosessimahdollisuuksia, kuten Stream API: n dataputkitoiminnoilla tuetaan.

Ne ovat nimettömiä menetelmiä (menetelmiä ilman nimiä), joita käytetään toiminnallisen rajapinnan määrittelemän menetelmän toteuttamiseen. On tärkeää tietää, mikä toiminnallinen käyttöliittymä on, ennen kuin likaat kätesi lambda-lausekkeilla.

Toiminnallinen käyttöliittymä

Toiminnallinen rajapinta on rajapinta, joka sisältää yhden ja vain yhden abstraktin menetelmän.

Jos katsomaan määritelmä Java standardin runnable liitäntä, huomaat miten se putoaa määritelmään funktionaalisen rajapinnan, koska se määrittelee vain yksi tapa: run().

Alla olevassa computeNamekoodinäytteessä menetelmä on implisiittisesti abstrakti ja ainoa määritelty menetelmä, joka tekee MyNamesta toiminnallisen käyttöliittymän.

interface MyName{ String computeName(String str); }

Nuolioperaattori

Lambda-lausekkeet esittävät uuden nuolioperaattorin ->Java-käyttöjärjestelmään. Se jakaa lambda-lausekkeet kahteen osaan:

(n) -> n*n

Vasen puoli määrittää lausekkeen edellyttämät parametrit, jotka voivat myös olla tyhjiä, jos parametreja ei tarvita.

Oikea puoli on lambda-runko, joka määrittää lambda-lausekkeen toiminnot. Voi olla hyödyllistä ajatella tätä operaattoria "tulossa". Esimerkiksi "n tulee n * n" tai "n tulee n neliö".

Kun otetaan huomioon toiminnallinen käyttöliittymä ja nuolioperaattorikonseptit, voit koota yksinkertaisen lambda-lausekkeen:

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")); }

Yllä olevan esimerkin muuttujat morningGreetingja eveningGreetingrivit 6 ja 7 viittaavat MyGreetingkäyttöliittymään ja määrittelevät erilaisia ​​tervehdysilmaisuja.

Kun kirjoitat lambda-lauseketta, on myös mahdollista määrittää nimenomaisesti parametrin tyyppi lausekkeessa seuraavasti:

MyGreeting morningGreeting = (String str) -> "Good Morning " + str + "!"; MyGreeting eveningGreeting = (String str) -> "Good Evening " + str + "!";

Estä lambda-lausekkeet

Toistaiseksi olen katsonut näytteitä yhden ekspression lambdoista. On olemassa toinen tyyppinen lauseke, jota käytetään, kun nuolioperaattorin oikealla puolella oleva koodi sisältää useamman kuin yhden lauseen, joka tunnetaan nimellä lohko 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")); }

Yleiset toiminnalliset rajapinnat

Lambda-ilmaisu ei voi olla yleinen. Mutta lambda-lausekkeeseen liittyvä toiminnallinen rajapinta voi. On mahdollista kirjoittaa yksi yleinen käyttöliittymä ja käsitellä erilaisia ​​palautustyyppejä tällä tavoin:

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-lausekkeet argumentteina

Yksi lambdojen yleinen käyttö on välittää ne argumentteina.

Niitä voidaan käyttää missä tahansa koodinpätkässä, joka tarjoaa kohdetyypin. Minusta tämä on jännittävää, koska sen avulla voin siirtää suoritettavan koodin argumenteiksi menetelmille.

Jos haluat välittää lambda-lausekkeet parametreina, varmista, että toiminnallinen liitäntätyyppi on yhteensopiva vaaditun parametrin kanssa.

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")); }

Nämä käsitteet antavat sinulle hyvän perustan aloittamaan lambda-lausekkeiden käytön. Katso koodisi ja katso, missä voit lisätä Java: n ilmaisuvoimaa.