
On był funkcjonariuszem, ona.. ona jakby nie istniała, nikt nie zwracał na nią uwagi. Szara myszka. Anonimowa. Ale mylilibyście się sądząc, że była jak każda inna. Nie, ona miała styl i klasę. To właśnie zbliżyło ich do siebie.
Historia od której zaczniemy nie ma szczęśliwego zakończenia.
Spotkali się przy wspólnym projekcie, on – ambitny Interfejs Funkcyjny i ona – Klasa Anonimowa. Chciałbym dopisać, że była to miłość od pierwszego wejrzenia, ale nie – wręcz przeciwnie.
[spokojna muzyka fortepianowa]
Interfejs wolał pracować samodzielnie, nurzać się w abstrakcji, tworzyć artystowskie koncepty pozbawione ciała, pobudzające immersję i budujące samoświadomość kodu. Gardził babraniem się w fizycznych obiektach, było to poniżej jego poziomu.
Klasa była pragmatyczką. Zajmowała się wszystkim i wszystko robiła najlepiej jak mogła. Nie skupiała się na jednym obiekcie jak jej starsze koleżanki, ale przeskakiwała od typu do typu. Pracowała metodycznie i skutecznie, choć mało kto doceniał jej wysiłki. Nikt nawet nie pytał jej o imię.
[wchodzą skrzypce]
Interfejs nie był tu wyjątkiem. Wykorzystywał ją. Kiedykolwiek potrzebował fizyczności – nalegał. A ona się godziła. Robiła wszystko co kazał. Chciał, żeby mu zwróciła Stringi – dała mu swoje Stringi. Chciał, żeby przyjęła jednocześnie dwa parametry? I to nie było dla niej tematem tabu. I tak to działało.. aż do feralnego marca 2014 roku.
[dołącza gitara basowa]
Nie wiadomo jak to się stało, byli przekonani, że uważali. Zawsze się zabezpieczali, wiedzieli jak to działa – chwila nieuwagi i wychodzisz z tego biznesu. A jednak, choć sprawdzali różne testy, wynik zawsze był ten sam:
->
Jednak wbrew temu, co wpierw myślała – Interfejs stanął na wysokości zadania, nie próbował się wymigiwać, że to nie jego dzieło. Przeciwnie – od razu zadbał o to aby to jego typ widniał w metryce urodzenia.
[wcześniejsze instrumenty cichną, pojawia się narastający dźwięk fletu]
Tuż przed terminem deploymentu pojawili się razem na badaniu kontrolnym u programisty prowadzącego. To miała być rutynowa wizyta, ale już na wejściu, po minie deva, zorientowali się, że coś było nie tak.
Płód ułożony poziomo. Będą komplikacje.
W ciągu tygodnia, stan Klasy mocno się pogorszył. Cierpiała, ale nie chciała przyjmować żadnych argumentów, które mogłoby negatywnie wpłynąć na stan dziecka. Interfejs był przy niej cały czas. Do samego końca.
18 marca 2014 roku Klasa odeszła pozostawiając po sobie cudowną córeczkę o imieniu Lambda. Nie zapominajmy o tym poświęceniu, które na zawsze odmieniło życie programistów na całym świecie.
[Szkot smętnie dusi dudy]

Przepraszam za ten przydługi wstęp, ale jeśli choć w połowie tak dobrze się bawiliście przy jego czytaniu jak ja przy pisaniu to było warto.
Wielokrotnie w moich tegorocznych wpisach zachwalałem kurs Javy na CodeGym, bo i faktycznie jest co polecać. Nie dość, że treściwy i przystępny to jeszcze cena taka, że prawie jak za darmo. Poważnie – roczny dostęp kosztuje tyle co jedna godzina mentoringu u pracującego seniora.
Ale, żeby nie było tak różowo – jedna rzecz dość szybko zaczęła mi w owym kursie przeszkadzać. Mianowicie – Java 5 o którą oparte były lekcje. Przez całe 40 poziomów i ponad tysiąc przerobionych zadań, ANI RAZU nie byłem zachęcany do samodzielnego tworzenia wyrażeń lambda. Owszem – takowe się pojawiały: w gotowym kodzie, w rozwiązaniach, w materiałach uzupełniających; ale i tak – koniec końców – kurs ukończyłem mając jedynie mętne pojęcie o tym czym są i jak się tworzy lambdy! A są to elementy codziennej pracy każdego kodera!
„Jak chcesz aby coś było zrobione porządnie – zrób to sam!”
Powyższe stwierdzenie jest jedną z dwóch* najważniejszych myśli przewodnich którymi kieruję się w życiu. W związku z tym postanowiłem samodzielnie zabrać się za temat i wyjaśnić istotę problemu, raz a dobrze – tak aby już nic nie trzeba było powtarzać. Ale, spokojnie – jeśli skupimy się tylko na praktyce (z pominięciem teorii rachunku lambda) to zleci szybciej niż się spodziewacie.
Do stworzenia standardowej lambdy, jak pokazałem to w ckliwej historyjce ze wstępniaka, będzie nam potrzebny interfejs funkcyjny – czyli taki z TYLKO jedną metodą abstrakcyjną (ale już metod domyślnych może być więcej) oraz klasa anonimowa.
Tworzymy sobie zmienną tak jak to robimy zazwyczaj, ale zamiast klasy ustawiamy typ na interfejs. Interfejsy nie mają konstruktorów, ergo – nie potrafią tworzyć obiektów. Operują w abstrakcji, więc po znaku równości nie możemy dać operatora „new” jak w przypadku zwykłej klasy:
Object object = new Object();
SomeInterface someInterface = new Some... //tak to nie zadziała!
Zamiast tego nasz wierny IntelliJ podpowie nam, aby stworzyć na szybko klasę anonimową, tylko dla tej zmiennej. Teraz w bloku {} musimy zaimportować wszystkie abstrakcyjne metody typującego interfejsu… et viola, klasa anonimowa w pełni gotowa!

Jeśli natomiast, nasz interfejs ma tylko jedną metodę (tzw. @FunctionalInterface) to zostanie nam zaoferowane przez IDE aby zamienić tę klasę na wyrażenie lambda.
Lambda jest niczym więcej jak skrótem pomijającym nieistotne elementy kodu.
Tworząc lambdę tak naprawdę tworzymy klasę anonimową z jedną metodą oraz wyznaczamy parametry, które ta metoda otrzyma. Spójrzmy jak rodzi się lambda, krok po kroku:

- Mamy gotową klasę anonimową, widzimy nazwę interfejsu i nazwę jego metody wraz z parametrami (2x String) oraz wartością zwracaną (również String);
- Lambda zastępuje klasę anonimową dzięki czemu wszystko mieści się w jednej linijcie kodu. Po lewej stronie „strzałki” są nazwy wrzucanych do metody parametrów – możemy je ustawić dowolnie. Zaś po prawej jest ciało metody – może to być jedna funkcja, a może być i cały blok {} ze zmiennymi i metodami oddzielonymi średnikiem. Najważniejszy warunek: Zwracany typ MUSI być taki sam jak w metodzie interfejsu-ojca.
- Jeszcze bardziej odchudzamy kod – słówko „return” nie jest do niczego potrzebne bo jest oczywiste. Nawiasy klamrowe dla tak krótkiej metody również można pominąć.
- Na koniec sztuczka iście magiczna – parametry są pozbawiane typowania! Możemy tak zrobić tylko dlatego, że typowanie jest zaciągane „w tle” z metody interfejsu-ojca.
Podsumowując, to jak wygląda lambda po utworzeniu zależy od trzech rzeczy:
- ilości parametrów metody interfejsu-ojca
- typu zwracanego przez tę metodę
- treści tej metody zaimplementowanej w lambdzie
Spójrzmy jak mogą się prezentować różne lambdy, oparte na nieco innych metodach:

Istotą lambdy jest zwięzłość kodu, dlatego kiedy ta zawarta w niej metoda zaczyna się rozrastać do kilku(nastu) linijek, być może lepiej – dla polepszenia czytelności kodu – pozostać przy klasie anonimowej.
I to w sumie tyle w temacie.
Teraz pozostaje już tylko praktyka, czyli własnoręczne pisanie „strzałeczek” w swoim kodzie. Jedna, druga, siódma, piętnasta… setna lambda i w końcu tak to nam wejdzie w nawyk, że będzie oczywiste niczym oddychanie.
300 Lambd
Powróćmy na koniec do cyklu poświęconego wzorcom projektowym. Mam nadzieję, że pamiętacie o bohaterach rodem ze świata fantasy, których przygody obrazowały nam jak tworzy się popularne wzorce. Czarodzieje, wojownicy, kapłani, druidzi… To uniwersum wzorców też ma swoje lore, a historia ich świata rozpoczęła się od zatrzymania marszu Armii Ciemności u schyłku drugiej ery.
300 bohaterów, członków elitarnego Zakonu Lambda stanęło naprzeciw stutysięcznego legionu nieumarłych pod przywództwem samego Króla Liczy! I choć wszyscy ci bezimienni bohaterowie polegli, pochód żywych trupów został zatrzymany, a nieumarły król pokonany. Tak rozpoczęła się trzecia era, która zaowocowała stworzeniem przepięknych wzorców projektowych.

Cały kod z tego artykułu znajdziecie na moim GitHubie. W następnym odcinku: odniesienia do metod (method references).
(*) to drugie to: „Lepszy mały, ale własny i z przodu, aniżeli duży, ale cudzy i z tyłu.”