Changes

Java Funkcionális interfész & Lambda

374 bytes added, 09:57, 12 August 2022
no edit summary
import java.util.function.Function;
public class MyLambadClass MyClassUsingFunctionalif {
private String variable1;
public MyLambadClassMyClassUsingFunctionalif(String a) {
this.variable1 = a;
}
<source lang="java">
MyLambadClass myLambadClass MyClassUsingFunctionalif MyClassUsingFunctionalif = new MyLambadClassMyClassUsingFunctionalif("adam");
MyFunctionImpl myFunction = new MyFunctionImpl();
myLambadClassMyClassUsingFunctionalif.processVariable(myFunction);
</source>
<br>
public static void main(String[] args) {
MyLambadClass myLambadClass MyClassUsingFunctionalif MyClassUsingFunctionalif = new MyLambadClassMyClassUsingFunctionalif("adam"); myLambadClassMyClassUsingFunctionalif.processVariable(var1 -> { return Integer.valueOf(var1.length()); });
}
Ami nem csinál mást, mint visszaadja a kapott string hosszát. Kívülről nézve a var1 nem értelmezhető, az mindig a lamdát futtató osztály egy osztály változója, kívülről nem megadható.
{{warning|Itt a 'var1' nem kívülről jövő, a metódus meghívásakor előállt paraméter! Ez a 'MyLambadClassMyClassUsingFunctionalif' belső változója, vagyis ide kívülről nem tudunk változót betolni a metódus meghívásakor }}
Tehát, ahogy ezt majd látni fogjuk a CompletionSage-nél, a 'FunctionalInterface'-t futtató osztályt kell előre feltölteni minden olyan változóval, amire szükség van a lamda kifejezés futtatására. A fenti példákban ez egyrészt a 'MyLambadClassMyClassUsingFunctionalif', vagy az első példában a ArrayList osztályok.
* A 'MyLambadClassMyClassUsingFunctionalif' konstruktorában adtuk át azt a string-et, amit a 'processVariable' feldolgoz, attól függetlenül, hogy milyen lamda kifejezéssel implementáljuk a funkcionális interfészét.
* Az ArrayList pedig belső változóiban tárolja
import java.util.function.Function;
public class MyLambadClass MyClassUsingFunctionalif {
private String variable1;
public MyLambadClassMyClassUsingFunctionalif(String a) {
this.variable1 = a;
}
Majd ha meghajtjuk a metódust ezzel az implementációval:
<source lang="java">
MyLambadClass myLambadClass MyClassUsingFunctionalif MyClassUsingFunctionalif = new MyLambadClassMyClassUsingFunctionalif("process_this_during_functional_if_call"); myLambadClassMyClassUsingFunctionalif.processVariable(new MyFunctionImpl());
</source>
Akkor a konzolon meg fog jelenni hogy: "38"
Persze, ezt lambdával is megadhattuk volna, akkor így nézne ki:
<source lang="java">
MyLambadClass myLambadClass MyClassUsingFunctionalif MyClassUsingFunctionalif = new MyLambadClassMyClassUsingFunctionalif("process_this_during_functional_if_call"); myLambadClassMyClassUsingFunctionalif.processVariable(input -> {return input.length();}); ---> 38
</source>
Itt inline, lambda definíciót használtunk. A generikus változói a '''Function''' funkcionális interfésznek (T és R) explicit lett definiálva azáltal, hogy a '''processVariable(..)''' belsejében a funkcionális IF (apply) String paraméterrel van meghívva és Integer-t vár vissza.
Na már most, ezt lehet nagyban egyszerűsíteni bármilyen olyan Osztály statikus vagy nem statikus metódusával, ami String-et vár és Integer-t ad vissza. Erre szolgála '''::''' operátor. Statikus metódus használata esetén nem kell példányosítani az osztályt, ennyi a különbség. Ami a lényeg: '''ezen osztálynak nem kell implementálnia a várt funkcionális interfész itt használt metódusát!!'''
<source lang="java">
MyLambadClass myLambadClass MyClassUsingFunctionalif MyClassUsingFunctionalif = new MyLambadClassMyClassUsingFunctionalif("process_this_during_functional_if_call"); myLambadClassMyClassUsingFunctionalif.processVariable(String::length); ----> 38
</source>
Ezzel azt mondjuk meg, hogy az '''R pply(T)''' helyett inkább hívd meg az '''Integer Sring.length(String input)''' metódust.
Akkor a '''getLengthOfImput(..)''' is átadható példányosítás után a '''::'' operátorral, mint behelyettesítés:
<source lang="java">
MyLambadClass myLambadClass MyClassUsingFunctionalif MyClassUsingFunctionalif = new MyLambadClassMyClassUsingFunctionalif("process_this_during_functional_if_call");
MyString myString = new MyString();
myLambadClassMyClassUsingFunctionalif.processVariable(myString::getLengthOfImput); ---> 38
</source>
Vagyis ahelyett hogy meghívná a funkcionális IF '''R apply(T)''' metódusát, inkább meghívja majd a '''getLengthOfImput''' metódust.
Tegyük fel, hogy van egy java osztályunk, amiben van egy metódus, ami felhasználja a '''MyFunction''' funkcionális if-et:
<source lang="java">
public class MyLambadClass MyClassUsingFunctionalif {
private String variable1;
public MyLambadClassMyClassUsingFunctionalif(String a) {
this.variable1 = a;
}
* Metódus referenciát használunk egy olyan osztály metódusával, ami String-et vár és gyárt belőle egy MyString-et
Simán megfogjuk a MyString osztályt és a konstruktorára hivatkozunk a '''MyLambadClassMyClassUsingFunctionalif.processVariable2(..)''' metódus használatakor.