7,540
edits
Changes
t
</source>
<br>
<br>
===Lambada kifejezés használata===
A fenti anonimus osztály definíció egy sokkal rövidebb Lambda kifejezéssel kiváltható, de csak akkor ha a szóban forgó interfész egy '''funkcionális interfész''', vagyis pontosan egy darab absztrakt metódusa van. A Lambda kifejezés szintaxisa az alábbi:
(arguments) -> {function body}
</pre>
Ahol az argomentumok az egy szem absztrakt metódus input paraméterei, a function bdoy-ban pedig leírjuk, hogy mit tegyen ezekkel az input paraméterekkel az implementáció. Az argumentumok típus nélküliek, a típusuk implicit következik a felhasználási módból, lásd lentebb.
* A paraméterek neve tetszőleges lehet, nem kell megegyezzen a funkcionális metódus paraméter neveivel. A sorrend viszont számít. A lényeg, hogy a body-ban az argumentumokban felsorolt nevekkel tudunk hivatkozni az input paraméterekre.
* Ha az interfész input paraméter generikus, csak akkor fognak típust kapni, amikor meghívásra kerül a kódban explicit a funkcionális generikus értékeket definiáljuk az interfész implementált metódusa, vagyis kiderül, hogy mivel etetjük me az implementált metódustváltozó létrehozásánál. * Ha a visszatérési érték is generikus az implementálandó metódusban, akkor annak vagy implicit következik a típusa a lambda kifejezésben használt visszatérési értéktől, vagy ha az függ is csak az input paraméter típusától, akkor majd a metódus meghívásakor adott felhasználásból fog típust kapni a metódusba használt input paraméterek típusától függőenkövetkezni.
* Ha a funkcionális interfész nem generikus, akkor az interfész input és return értékéből már explicit következik a lambdában használt paraméterek és visszatérési értékék típusa.
Nézzünk egy konkrét példát. A 'MyFunction' egy funkcionális interfész, mert pontosan egy absztrakt metódusa van: 'MyString process(String)'. Tehát a lambda kifejezéssel ennek a 'process(..)' absztrakt metódusnak az implementációját kell definiálni:
<source lang="java">
MyFunction fm = var1 -> { System.out.println("inside lambda body"); return new MyString(var1); }; System.out.println("Start");
fm.process("input");
System.out.println("End");
</source>
Láthatjuk, hogy a 'MyFunction' egy szem absztrakt metódusát egy lambda kifejezéssel definiáltuk, amivel egyben el is készítettük a MyFunction implementációjának példányosítását. A 'MyFunction'-enk egy darab absztrakt metódusa van, az alábbi szignatúrával: 'MyString process(String)', ebből következik, hogy a '->' elé pontosan egy változó nevet kell kitaláljunk, ami bármi lehet, lényeg, hogy a body-ban ezzel a névvel tudunk rá hivatkozni. Mi itt 'var1' nevet találtunk ki, aminek a típusa 'String', mivel a 'process(..) metódusban egy darab String input paraméter van. Ha a 'process(..)' generikus inputtal rendelkezne, akkor a lambada-ban a 'var1' nek a típusa csak használat közben derülne ki, majd később erre is látunk példát.
<br>
Fontos, hogy a 'var1'-nek a globálisan semmi jelentése nincs, nem létező változó a fenti kódot futtató kontextusban. Ezt úgy kell elképzelni, mint egy metódus leírója, ami majd akkor kerül meghívásra csak, ha meghíjuk programozottan a 'process(..)' metódust, csak akkor fog feltöltődni értékekkel. <br>
Az stdout-ra a következő kerül:
<pre>
Start
inside lambda body
End
</pre>
<br>
<br>
Tehát az alábbi két sor egyenlő:
<presource lang="java">
MyFunction fm = var1 -> { return new MyString(var1); };
fm.process("input");
MyFunction fm = new MyFunctionImpl();
fm.process("input");
</presource>
!!!Mit fontos itt látni: A lambda definiálásának a sorába még nem fut le a lambda törzsében megadott kód, vagyis ez: return new MyString(var1);!!!
</source>
<br>
Definiáljuk a 'MyFunctionGeneric' interfész absztrakt metódusát egy lambda kifejezéssel. A 'MyFunctionGeneric fm' változó létrehozásakor már definiálni kell az R és T és H típusokat, ebből fog következni, hogy a lambada-ban használt paraméter listának milyen értékei vannak, hogy mi kell legyen a visszatérési érték.
<br>
<br>
Az alábbi példában létrehoztuk az fm3 'MyFunctionGeneric' változót, és itt meghatároztuk, hogy a visszatérési érték Integer, és a bement két String. A lambda kifejezés input paramétereiben már két értéket kell megadni, ezért zárójelet kell alkalmazni.
<source lang="java">
MyFunctionGeneric<Integer, String, String> fm3 = (myInput1, myInput2) -> myInput1.length();
fm3.doIt("my input", "my input2");
</source>
Az input argumentumoknak megint csak bármilyen nevet megadhatunk, a fenti kódot futtató kontextusban nem léteznek, ez csak egy metódus tervrajz, nem metódus futtatás. A 'myInput1' és 2-nek a típusa következik az fm3-ban megadott generikus típusokból, vagyis mind a kettő String. A visszatérési érték pedig Integer. Ha a lambda body-ban nem akarunk több soros művelet végrehajtani, csak egy 'return (one line logic)' sort tartalmazna, akkor a 'return' kulcsszó elhagyható. Fontos megint csak látni, hogy a doIt(..) metódus hívás hatására fog csak lefutni a lambda-ban definiált kód.
<br>
<br>