Changes

Java Funkcionális interfész & Lambda

3,511 bytes added, 08:41, 15 August 2022
Constructor reference in Enum
A [[ Java Enum]] cikkben láthattuk, hogy az enumoknak is lehet konstruktort, metódusokat és osztály változókat készíteni. Itt az Ismétlés képen itt egy enum, aminek van egy int változója, és ezt a csavarkonstruktor inicializálja, vagyis minden ENUM érték esetében meg kell adni egy 'int' számot is, hogy készítünk amit el fog rakni az enum-nak Funkcionális IF változót, amit a konstruktor inicializál. példányba: <source lang="java">public enum AdamTest {
LALI(2),
ADAM(3)
;
private int enumInt;
private AdamTest(int a) { this.enumInt=a; }}</source> <br><br>Ha olyan osztály változót készítünk az ENUM-nak, ami egy funkcionális interfész, és ezt szintén a konstruktorral inicializáljuk, akkor minden egyes ENUM érték esetében a konstruktorban meg kell adni ennek a funkcionális interfésznek a definícióját.  Tegyük fel, hogy adott az alábbi osztály, ami egy saját String változat: <source lang="java">public class MyString {  private String input;  public MyString(String input) { System.out.println("MyString consturctor is called with input:" + input); this.input = input; }  public String getInput() { return input; }}</source><br>Tegyük fel, hogy adott az alábbi funkcionális IF:<source lang="java">@FunctionalInterfacepublic interface MyFunction { MyString process(String input);}</source>Itt a 'process(..)' implementáció egy string-et vár és egy MyString-et ad vissza.  <br>Tekintsük az alábbi ENUM-ot. Az enum-nak van egy MyFunction típusú funkcionális if osztály változója, amit a konstruktor inicializál. Tehát minden enum értéknek meg kell adni egy MyFnction implementációt. <source lang="java">public enum MyEnum2 {  ENUMV1(..<MyFunction implementáció>...), ;  private final MyFunction function;  private MyEnum2(MyFunction function) {  System.out.println("ENUM constructor is called with input"); this.function = function; }  public MyFunction getFunction() { return function; }}</source><br>Láttuk már, hogy elvi szinten egy funkcionális if megadására 4 lehetőségünk van, azonban itt most nem használhatjuk mindent: * Implementációt készítünk Funkcionális interfész metódusokat a MyFunction-hez: Ez nem fog működni, mert az enum példányosításakor statikus kontextusban vagyunk, nincs hol példányosítsuk a funkcionális if implementációnkat, nem olyan mint amikor enum kívül, normál class metódusban használjuk. <br><br> * lambda kifejezésben adjuk meg inline: ez már működő képes.<source lang="java">public enum MyEnum2 {  ENUMV1(var1 -> { System.out.println("ENUM lambda is called with input: " + var1); return new MyString(var1); }), ;</source>{note||Az itt megadott kód ugyebár nem fog lefutni a a MyEnum2 példányosításakor. A példányosításkor a konstruktorban ezzel a lambda kifejezéssel csak megadott a MyFunction if tervrajzát, vagyis hogy a MyFunction osztály változó rakjon bele egy olyan "virtuális" implementációs példányt, amiben az itt megadott 'MyString process(String)' implementáció található. Tehát a lambda-ban megadott kód rész csak akkor fog lefutni, ha meghívjuk explicit a MyFunction.process(..) metódust, így: <source lang="java"> MyEnum2 myEnum21 = MyEnum2.ENUMV1; myEnum21.getFunction().process("process input"); <<---- itt fut csak le a konstruktorban megadott lambda</source>Ekkor az írja az stdout-ra: <pre>ENUM constructor is called with inputENUM lambda is called with input: process inputMyString consturctor is called with input:process input</pre><br><br>  * 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:  <br><br> * Konstruktor referenciát használunk<br>