2014. december 1., hétfő

Java SE 8 - Lambda kifejezések

A Java SE 7 újdonságai után haladjunk a korral és nézzük meg a Java SE 8 leginkább várt feature-ét, a Lambda kifejezéseket. A Lambda kifejezések és a hozzá kapcsolódó újítások (Stream API, funkcionális interfészek, alapértelmezett metódusok, metódus referenciák) azért is jelentősek, mivel a Java SE 5 verzióban megjelent generikusok és annotációk óta nem volt ilyen nagy változás, ami ennyire átalakította volna a Java nyelv használatát. A lambda kifejezésekkel tisztább, sokkal kifejezőbb és így karbantarthatóbb kódot írhatunk valamint már nyelvi szinten is kihasználhatjuk a több processzoros gépek párhuzamos feldolgozási képességeit. De mik is azok a lambda kifejezések?

A lambda kifejezések olyan névtelen metódusok, amiket ott írunk meg ahol ténylegesen használunk. Egy remek példa erre az anonim osztályokkal megvalósított Swing-es eseménykezelők átírása lambda kifejezések használatával:
Button btn = new Button();

//anonymous inner class
btn.addActionListener(new ActionListener() {
 public void actionPerformed(ActionEvent event) {
  System.out.println("print");
 }
});

//lambda expression
btn.addActionListener(event -> System.out.println("print"));
A lambda kifejezéssel magát a viselkedést, tehát az implementációt adjuk át az addActionListener() metódusnak, nem pedig egy olyan objektumot ami megvalósítja a kívánt interfészt. A fenti példa alapján beazonosítható a Lambda kifejezések szintaktikája, azaz definiáljuk a paramétereket - akár a típus megnevezése nélkül - (event), a nyíl tokent (->) majd az implementációt (System.out.println("print")).

A továbbiakban nézzünk meg néhány mintát a Lambda kifejezésekre. Az első példában egy Comparator-nak adjuk meg az implementációját, majd a 10 és 20 értékre vonatkozólag megjelenítjük az eredményt. A második példa pedig egy argumentum nélküli, több soros implementációval rendelkező Lambda kifejezést mutat.
// sample1
Comparator<Integer> myComparator = (a, b) -> a.compareTo(b) * -1;
System.out.println(myComparator.compare(10, 20));

// sample2
int i = 10;
// i=777; fordítási hiba, mivel az i változó "effectively final"
Runnable r2 = () -> {
 int c = i + 8;
 System.out.println("Adder: " + c);
};
r2.run();
Érdemes megemlíteni, hogy az i változó értékét nem módosíthatjuk annak ellenére, hogy a final módosító nincs kiírva, mivel azt egy lambda kifejezésben is használjuk. (effectively final)

A cikk hamarosan folytatódik, legközelebb a Lambda kifejezésekhez szorosan kapcsolódó funkcionális interfészekről fogok blogolni. Egyébként használja már valaki a Java 8-ast éles fejlesztéshez? :)

4 megjegyzés:

  1. "Egyébként használja már valaki a Java 8-ast éles fejlesztéshez?"
    Igen, mi használjuk a Java 8-at a TOPdesk-nél.

    VálaszTörlés
    Válaszok
    1. Aha, és milyen gyorsan ment az átállás az új API-k használatára?

      Törlés
  2. Bőven Java6/7 +tomcat6/7-tel van. (Svájc, befektetési bank)

    VálaszTörlés