1. Függvénymódszerek
Ha egy interfésznek csak egy metódusa van , akkor az adott interfész típusú változóhoz lambda-kifejezés (lambda-függvény) által adott érték rendelhető . Az ilyen interfészek funkcionális interfészekként váltak ismertté (miután a Java hozzáadta a lambda funkciók támogatását).
Például a Java-nak van a Consumer<Type>
felülete, amelyen a accept(Type obj)
metódus. Miért van szükség erre a felületre?
A Java 8-ban a gyűjteményeknek van egy forEach()
metódusa, amely lehetővé teszi, hogy a gyűjtemény egyes elemeihez valamilyen műveletet hajtson végre . És itt a funkcionális felületet használják a művelet átadására a metódusnak. Consumer<T>
forEach()
A következőképpen jelenítheti meg a gyűjtemény összes elemét :
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "Hello", "how's", "life?");
list.forEach( (s) -> System.out.println(s) );
A fordító a fenti kódot az alábbi kódra konvertálja:
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "Hello", "how's", "life?");
list.forEach(new Consumer<String>()
{
public void accept(String s)
{
System.out.println(s));
}
});
Az első verzió határozottan rövidebb, mint a második. És bár a lambda-kifejezéseket tartalmazó kód nehezen olvasható, a névtelen belső osztályokkal rendelkező kód néha még nehezebben olvasható.
2. Módszer hivatkozás
A lambda kifejezés kódja azonban még rövidebbre is írható.
Először is elhagyhatja a paraméter körüli zárójelekets
:
list.forEach( (s) -> System.out.println(s) );
list.forEach( s -> System.out.println(s) );
Ezt csak akkor lehet megtenni, ha van egy paraméter . Ha több paraméter is van , akkor zárójeleket kell használnia .
Másodszor pedig így írhatod:
list.forEach( System.out::println );
Ez pontosan ugyanaz a jelölés. Vegye figyelembe, hogy a . után nincs zárójel println
.
Itt ugyanaz a kód van - egy metódushívás:
object::method
x -> object.method(x)
Gondoljunk csak bele: a gyűjtemény minden egyes eleméhez szeretnénk valamilyen műveletet végrehajtani list
. Ha a művelet egyetlen függvényhívás (például println()
), akkor logikus, hogy egyszerűen átadja a függvényt a metódusnak paraméterként.
De hogyan magyarázzuk el a fordítónak, hogy inkább át akarjuk adni a metódust, mint meghívni? Ehhez a pont operátor helyett két kettőspontot használunk a metódus neve előtt. Egy kettőspont már használatos a háromtagú operátor jelzésére.
Ez a legegyszerűbb és legkompaktabb jelölés.
3. Konstruktor
A kettős kettőspontos metódushivatkozások nagyon hasznosak, ha I/O adatfolyamokkal dolgozunk. Ezt egy kicsit később látni fogod.
Addig is beszéljünk a módszerreferencia átadásának 3 népszerű módjáról:
Hivatkozás egy objektum metódusára
Egy objektum metódusára való hivatkozás átadásához valami ilyesmit kell írnia . Ez a kód egyenértékű a .object::method
x -> object.method(x)
A speciális this
és super
a változók használhatók objektumként.
Hivatkozás egy osztály metódusára
Egy statikus metódusra való hivatkozás átadásához valami ilyesmit kell írnia . Ez a kód kódszerűvé alakul átclass::method
x -> class.method(x);
Konstruktorra való hivatkozás
A konstruktor hasonlóan viselkedik, mint egy statikus osztálymetódus, így hivatkozást is átadhatunk egy konstruktornak. Így néz ki: .class::new
Például megkerülheti a gyűjtemények típustörlését, és átadhat a toArray()
metódusnak egy hivatkozást egy konstruktornak, amely létrehozza a kívánt tömböt:toArray(int[]::new);
GO TO FULL VERSION