V tomto a v nasledujúcich článkoch sa pozrieme na zúbok lambda výrazom. Budeme si ich vysvetľovať úplne dopodrobna, aby sme ich pochopili a využívali. Obsahovo sa zameriame na tieto oblasti:
- porozumenie lambda výrazom,
- použitie lambda výrazov,
- funkcionálne rozhrania (functional intefaces),
- referencie metód (method references),
- vylepšenia na kolekciách.
Prečo použiť lambda výrazy? Povieme si pár odrážok, prečo ich používať.
- povoľuje použiť takzvané funkcionálne programovanie, čo je doteraz niečo, povedal by som čudné, keďže Java je objektovo orientovaný jazyk,
- sprehľadňujú kód, lepšia čitateľnosť v niektorých prípadoch, kde by sme použili viacero zbytočných riadkov, aby sme napísali to isté.
Možno sa zamýšľaš, prečo používať funkcionálne programovanie v jazyku, ktorý je objektovo orientovaný. Už nie je OOP tak dobré? Už zanikne? Nie, nezanikne a java je a myslím si, že stále bude objektovo orientovaný jazyk. Toto funkcionálne programovanie ber len ako ďalší nástroj, ktorý ako vývojár máš vo svojej ruke.
Pri OOP sú vývojári zvyknutí rozmýšľať v podstatných menách, v objektoch, v triedach. Napríklad Pes šteká. Štekanie je súčasťou Psa. Tým pádom metóda, ktorá bude zabezpečovať psie štekanie, je súčasťou triedy Pes.
Niekedy ale potrebujem kus kódu, metódu – alebo inak povedané funkciu, ktorá nepatrí do žiadnej triedy špeciálne.
Podsunutie chovania do metódy
Uvažuj nad tým, že máš metódu, ktorá na konzolu vypíše nejaký text. Napríklad staré známe Hello World. Pre tento účel by sme si vytvorili triedu, ktorej by bola metóda na vypísanie Hello Word. Túto metódu by sme potom vypísali na konzolu v main metóde. Príklad v idea Lambda2.
Našou úlohou bude teraz prerobiť tento kód tak, aby som danej metóde podsunul správanie a vo vnútri tej metódy sa len vykoná to správanie. Ukážme si na príklade.
Takže sme spravili, čo sme chceli. Do metódy sme podsunuli správanie ako argument a potom sme ho vykonali. Ale nie tak presne. Do metódy sme podsunuli niečo, čo má v sebe správanie. Podsunuli sme implementáciu rozhrania, ktorá má v sebe metódu, ktorá vykoná očakávané správanie sa.
Práve tomuto chcú lambda výrazy zabrániť. Chcú zabrániť tomu, aby sme podsúvali objekty, ale chcú, aby sme podsúvali funkcie.
Namiesto tohto:
public void printHelloWord(IHelloWord helloWord){
helloWord.sayHello();
}
chceme do metódy vložiť nejakú akciu, nejakú funkciu. Tento prístup umožňuje správať sa k funkciám ako k hodnotám.
public void printHelloWord(funkcia){
funkcia();
}
Ak napíšem String meno = “Jaro”; tak som hodnotu Jaro pridelil do premennej meno. Teraz sme ale načrtli, že do nejakej premennej by sme chceli vložiť blok kódu, ktorý prezentuje našu funkciu. Takže blok kód by sa stal hodnotou a tá by sa dala vložiť do premennej. Takže tam, kde používam danú premennú, tak tam používam aj danú funkciu, ktorá je v nej.
Pre predstavivosť, chceme dosiahnuť toto:
premennaSFunkciou = public void sayHello() {
System.out.println("HelloWord impls");
}
Toto je možné pomocou lambda výrazov. Najprv sa ale pozrime na tento kus kódu a povedzme si, čo nepotrebujeme:
- public – označuje mi, či je niečo verejne dostupné mimo triedy, dáva zmysel v kontexte triedy, tu ale prideľujeme do premennej, tak to nepotrebujeme, lebo funkcia je dostupná tomu, kto pracuje s danou premennou.
premennaSFunkciou = void sayHello() {
System.out.println("HelloWord impls");
}
- názov sayHello = ak pristupujeme k hodnote, ktorá je v premennej, tak ku nej pristupujme názvom premennej, v našom prípade je názov premennej premennaSFunkcou, takže ani druhé meno nepotrebujeme.
premennaSFunkciou = void () {
System.out.println("HelloWord impls");
}
- typ návratovej hodnoty – pri písaní lambda výrazov nemusím písať, aký je návratový typ, prekladač vie, podľa vnútra metódy, čo sa vracia.
premennaSFunkciou = () {
System.out.println("HelloWord impls");
}
Toto ale ešte nie je labmda výraz. Ak napíšem šípku (pomlčka - a znamienko väčšie >) medzi zátvorky a blok kódu, tak vtedy sme vytvorili labmda výraz.
premennaSFunkciou = () -> {
System.out.println("HelloWord impls");
}
Ak metóda obsahuje len jeden riadok, teda nie viac riadkov, tak je možné ďalej upraviť tento výraz a to tak, že odstránime zložené zátvorky. Ak je viac riadkov, tak zložené zátvorky ponecháme.
premennaSFunkciou = () -> System.out.println("HelloWord impls");
Teraz si už vieme predstaviť, spraviť, to, že pošleme funkciu ako parameter metódy a vo vnútri spustíme danú funkciu.
public void printHelloWord(------){
-----();
}
Do metódy môžeme vložiť ako argument pri volaní metódy priamo lambda výraz.
printHelloWord(() -> System.out.println("HelloWord impls")){
Príklady
Napíš metódu, ktorá zoberie ako parameter číslo a vynásobí ho 5timi.
nasobokPiatichFunkcia = public int nasobokPiatich(int i){
return i*5;
}
Prepíšeme to na lambda výraz, vyškrtám všetko, čo nepotrebujem. Teda názov, návratovú hodnotu a modifikátor prístupu.
nasobokPiatichFunkcia = (int i){
return i*5;
}
Napíšeme tam šípku a keďže riadok je tam len jeden, tak vieme odmazať kučeravé zátvorky.
nasobokPiatichFunkcia = (int i) -> return i*5;
Tu máme ďalšiu pomôcku, alebo možnosť škrtať. Keďže java kompilátor pozná vnútro metódy a vie, čo má vrátiť, môžem vymazať aj return.
nasobokPiatichFunkcia = (int i) -> i*5;
Keď máme jednoriadkový lambda výraz bez zložených zátvoriek, tak je nevyhnuté nepoužívať return.
Sčítanie
scitanieFunkcia = (int a, int b) -> a+b;
Odčítanie
odcitanieFunkcia = (int a, int b) -> a-b;
Bezpečné delenie
bezpecneDelenieFunkcia = (int a, int b) -> {
if(b==0) {
return 0 ;
}
return a/b;
};
Spojenie reťazcov
stringJoin = (String x, String y) -> x.concat(y);
Stále sme v Jave. Teda v typovom jazyku. Aké sú typy týchto premenných, ktoré v sebe držia lambda výrazy?
Video:
Ak ťa viac baví počúvať a pozerať, tak si môžeš pozrieť sériu videí o lambda výrazoch v kurze Java pre pokročilých.
Záver
Ak by si sa chcel dozvedieť o Jave viac alebo si nepochopil všetko, tak som aj pre teba pripravil online
kurzy o Jave na https://skillmea.sk.
Zakomponujem aj malú reklamu. V spolupráci s tvorcami stoličky
Neseda.com ti ponúkam s kódom/kupónom JaroslavBeno 10% zľavu (aplikovateľná aj na zľavnenú stoličku).
Ja som Jaro a my sa vidíme, počujeme ak Boh dá nabudúce.
Čaves.