Skip to content

Witaj w Świecie Jutra!

  • Technologie jutra
  • Sprzęt jutra
  • Aplikacje jutra
  • Programowanie
  • Księga Drogi
  • Renowacja
  • Różności
  • Archiwum
  • Autor
  • Home
  • Wszystko
  • Programowanie funkcyjne – Odniesienia do metody
  • Programowanie
  • Wszystko

Programowanie funkcyjne – Odniesienia do metody

Jakub Raczkowski 25 marca 2024

W poprzednim wpisie wyjaśnialiśmy sobie czym tak właściwie jest ta lambda w Javie i wyszło nam, że to taka na szybko stworzona metoda w na szybko stworzonej klasie w oparciu o jakiś interfejs funkcyjny. Ale co gdyby – czysto hipotetycznie! – owa potrzebna nam metoda już gdzieś w jakiejś klasie istniała i nie trzeba byłoby jej pisać od zera?

Zacznijmy od czegoś tak prostego jak tylko się da. Czegoś, co uczymy się już pierwszego dnia naszej przygody z Javą (i chyba z każdym innym językiem programowania, tylko w mniej lub bardziej zmienionej postaci):

System.out.println(„Hello world!”);

Co robi ten kawałek? Wiadomo – wyświetla napis w nawiasach: Hello world! bezpośrednio w konsoli. Ale jak dokładnie to się dzieje?

  • Co to jest ten „System”?!
  • Co to jest ten „out”?!!
  • Co to jest ta funkcja „println()”?!!!
System jest klasą, która „zagląda” level wyżej niż sam projekt.

System, to klasa, która nie tworzy żadnych obiektów (jej konstruktor jest prywatny), za to posiada szereg statycznych metod, które dotyczną nie tyle samej aplikacji, którą budujemy, co systemu – platformy na której się ona znajduje. Dla przykładu:

  • System.currentTimeMillis() wyświetla ilość milisekund która upłynęła od „daty zero” (1 stycznia 1970, data uważana powszechnie za początek ery systemów unixowych)
  • System.gc() z kolei ma w założeniu uruchamiać „odśmiecarkę” JVM (ang. „garbage collector”), ale, że GC ma własne widzimisię to de facto – ta metoda nie robi nic
  • System.exit(0) kończy działanie aplikacji (dla wartości 0 kończy naturalnie, a dla 1 zupełnie jakby wyskoczył jakiś błąd)
„out” to statyczna zmienna typu PrintStream, już podłączona do konsoli

Klasa System ma również kilka statycznych zmiennych odnoszących się do konkretnych obiektów z których metod możemy korzystać:

  • System.out.println() operuje na obiekcie „PrintStream out” dzięki któremu możemy wypisać dowolny tekst w konsoli
  • System.err.println() działa podobnie jak System.out.println() ale służy do wyświetlania błędów, więc jej wyniki są zawsze w kolorze czerwonym
  • System.in to obiekt typu InputStream – uruchamiany jest strumień wejściowy w konsoli, ale inny obiekt musi go jakoś obsłużyć, np. Scanner
PrintStream printStream = new PrintStream(System.out);
printStream.println("Tak również wyświetlimy tekst w konsoli");

Scanner scanner = new Scanner(System.in); //a tak otworzymy strumień wejściowy
int i = scanner.nextInt(); //i przypiszemy wprowadzoną liczbę do zmiennej i 

Dobrze, skoro już jest jasne jak działa popularny System.out.println() to teraz zastanówmy się czym do cholery jest poniższy kawałek:

System.out::println

Dwa sposoby na osiągniecie tego samego efektu. Który lepszy?

Jak widać na obrazku powyżej, jest to coś powiązane z lambdą, ale inne – jeszcze krótsze. Zaś efekt działania pozostaje ten sam – tu i tam tekst wyświetla się w konsoli.

Wróćmy do kroków niezbędnych do utworzenia lambdy z poprzedniego odcinka i dodajemy do tego ten nowy kawałek z podwójnym dwukropkiem:

Jak powstaje lambda + jak powstaje odniesienie

Wyraźnie widać, że początek jest ten sam. Robimy klasę anonimową, a potem po kolei usuwamy zbędne elementy aż zostaje „goła” lambda. Ale czasami, tylko w sprzyjających warunkach, możemy pójść inną drogą – odnosząc się do już gotowej metody.

A jakie warunki są „sprzyjające”?

Po pierwsze musimy wybrać taką metodę która jest bliźniaczo podobna do metody zadeklarowanej w interfejsie z którego korzystamy. O ile nazwy mogą się różnić to już:

  • typ zwracany MUSI być ten sam
  • liczba użytych parametrów MUSI się zgadzać
  • typy użytych parametrów MUSZĄ być dokładnie takie same
  • no i oczywiście ta metoda musi robić to co nam akurat potrzeba
Od teraz kapłanów mogę tworzyć jeszcze szybciej!

Największym problemem w zrozumieniu jak działa method reference jest to, że nie widać tam żadnych zmiennych. Nawet w lambdzie, pierwszym co robimy jest stworzenie sobie na szybko jakiejś zmiennej:

Interface interface = zmienna -> zmienna.jakaśMetoda();
interface.metodaInterfejsu(tuWrzucamyParametrZmienna);

Pamiętajmy na jakiej zasadzie działa wyrażenie lambda – ta tymczasowo stworzona zmienna jest pozbawiona typu tylko i wyłącznie dlatego, że jest on kopiowany z metody interfejsu. Odniesienia działają w ten sam sposób, tylko, że jeszcze bardziej.

Kiedy wpiszemy np. String::trim, czyli metodę klasy String, która pobiera jeden ciąg znaków, usuwa z niego spacje z przodu i z tyłu, a następnie go zwraca, JVM sprawdza, czy metoda naszego interfejsu typującego ma podobną sygnaturę:

  • zwraca String? zgadza się!
  • ma jeden parametr? zgadza się!
  • ten parametr jest typu String? zgadza się!

Wszystko ok, można użyć odniesienia do metody. Albo przeciwnie – coś nie bangla i trzeba jak jaskiniowiec korzystać ze zwykłej lambdy.

Kiedy już nauczymy się tworzyć odniesienia do metod, nasz kod stanie się jeszcze bardziej zwięzły – nie dość, że będzie krótszy to jeszcze od razu będzie widać co tam się dzieje.

Interface interface = String::trim;
interface(tuWrzucamyJakiśString);
Kawałek „::new” po prostu tworzy obiekt w oparciu o dany input.
Różne efekty użycia odniesień.

forEach()

Odniesienia do metod są bardzo często spotykane w Stream API (o tym w kolejnym odcinku) oraz w metodzie forEach() która jest estetycznym zamiennikiem zwykłego iterowania po elementach kolekcji/tablicy znanego z Javy 5.

Wcześniej trzeba było podać typ elementów kolekcji, zadeklarować zmienną i podać nazwę kolekcji w której będziemy przebierać. Następnie blok {} i możemy w końcu wrzucać elementy do pasujących nam metod. Sporo tego, szczególnie jeśli chcemy tam użyć tylko jednej metody. Z pomocą przychodzi właśnie funkcja forEach sparowana z method reference:

Nie wiem jak wy, ale ja od dzisiaj znacznie rzadziej będę korzystał z domyślnej iteracji.

Teoria teorią, ale jak to ogarnąć na co dzień?

Wyobraźmy sobie przeciętnego człowieka: głowa, 2 ręce, 2 nogi, brzuch, tyłek i tak dalej. Stwórzmy sobie obiekt takiego człowieka (Person) w kodzie, niech jego klasa implementuje interfejs Living z jedną metodą do() czyli „zrób”:

Living person = new Person();
person.do();

Podsumujmy: mamy człowieka i chcemy, żeby coś zrobił. Używając normalnej lambdy musielibyśmy za każdym razem pisać co dokładnie chcemy żeby gościu wykonał. Ale korzystając z odniesienia do (już istniejącej) metody wystarczy, że podamy klasę gdzie ta metoda się znajduje i jej nazwę:

Living p1 = Frog::jump;
Living p2 = Cook::prepareDinner;
Living p3 = Sleep::haveNap;
Living p4 = Animal::eat;
Living p5 = Rock::standStill;
Living p6 = Job::work;
Living p7 = Rezus::gibaj;


Tak jak z każdym nowym skillem, kluczem do wprawy jest regularna praktyka, ale tym zajmiemy się w następnym odcinku – poświęconym strumieniom, czyli zagadnieniu gdzie lambdy i odniesienia pojawiają się w ilościach hurtowych.

Na dzisiaj tyle, kod z tego odcinka znajdziecie na moim GitHubie.

Tags: functional programming

Continue Reading

Previous: Programowanie funkcyjne – Lambda
Next: Programowanie funkcyjne – Strumienie (1/2)

Related Stories

Mageege Moon104 – test niskoprofilowego mechanika
  • Sprzęt

Mageege Moon104 – test niskoprofilowego mechanika

11 marca 2025
Przebranżowienie cz.4
  • Programowanie

Przebranżowienie cz.4

27 lutego 2025
Smartfon Jutra
  • Sprzęt

Smartfon Jutra

15 lutego 2025

Ze świata

  • Antyweb
  • Kwantowo
  • Dwóch po dwóch
Badacze zbadali stan W splątania kwantowego i osłupieli. Oto, co im wyszło
ChatGPT złożył użytkownikom obietnicę. Albo nowe funkcje, albo reset limitów
A jednak. Dwie wielkie platformy z filmami i serialami połączą się w jednego giganta!
Garmin po cichu prezentuje zegarek Enduro 4. Zmian jest jak na lekarstwo
Błagam, zaorajcie już ten Alert RCB. To potwarz dla wszystkich Polaków
Facebook zmieni się nie do poznania. Pójdzie w ślady TikToka
250 zł zniżki na Garmina. Taka cena tylko tutaj
GMK TriggerKey ma sprawić, że nie będzie już powrotu do zwykłego WASD
Nowy trik Samsunga. Szybsze ładowanie flagowca
ChatGPT idzie śladami Claude. Niewidzialny znak wodny trafi do użytkowników z Europy
Łatwiej i szybciej - duet Samsung Bespoke AI
Znakomity mikrofon i 110 godzin na baterii. Testujemy Corsair HS80 v2 MAX
Chcesz by Windows się blokował, gdy odejdziesz od komputera? Tak zrobisz to automatycznie
Oto nowy iOS 27.2. Co nowego w kolejnej becie systemu?
Takiego zestawu LEGO jeszcze nie było. Prawdziwa gratka dla fanów
Polacy w końcu zaczną oglądać Apple TV. Na to czekali latami
Masz Amazon Prime? W nowe Gwiezdne Wojny zagrasz bez dodatkowych opłat
Amazon zaszalał. Przepotężny powerbank Ankera za pół ceny
Samochód zarejestrujesz z domu. Pomoże mObywatel
GIGABYTE upchnął tu niemal wszystko. Tak powinien wyglądać monitor dla wymagającego gracza
O powstawaniu kamieni drogą doboru naturalnego
Świat upomina się o „właściwe” proporcje
Kosmiczna panorama i superkoronograf – co przyniesie nam Teleskop Nancy Roman?
O czym szepczą między sobą bozony Higgsa?
Wszechświat w trzech aktach – recenzja książki “Astronomia, kosmologia i astronautyka”
Wielka przerwa Wielkiego Zderzacza
A gdyby tak przeciąć foton na pół?
SpudCell – syntetyczna komórka, która udaje życie
Mega upał, omega manipulacja
Coraz więcej dowodów, coraz mniej pewności
WRZESIEŃ BĘDZIE MOCNY… Premiery gier, na które czekamy – Mamy do pogrania
Całkiem dobry film ten nowy Spider-Man: Brand New Day 🕷️ – No Movie Ci #18
Scyzorykon 2026, Galaxy Fold8 i całkiem nowy Spider-Man – Odcinek #137
Sprawdziliśmy Scyzorykon 2026 od środka!
Co się działo na Fantasy & Magic Con w Warszawie?
Porozmawiajmy o Steam Machine 🎮👀
Przedsprzedaż GTA VI, Stargate i gry, które paliły sprzęty – Odcinek #136
Relacja z CD-Action Expo 2026
Tańszy Game Pass, droższy Steam Deck i Internet 0202122 – Odcinek #135
Elite Dangerous. Gra, z której odchodzi się po cichu

To może cię zainteresować:

Mageege Moon104 – test niskoprofilowego mechanika
  • Sprzęt

Mageege Moon104 – test niskoprofilowego mechanika

11 marca 2025
Przebranżowienie cz.4
  • Programowanie

Przebranżowienie cz.4

27 lutego 2025
Smartfon Jutra
  • Sprzęt

Smartfon Jutra

15 lutego 2025
Czym jest Swagger?
  • Programowanie

Czym jest Swagger?

22 lipca 2024
  • Technologie jutra
  • Sprzęt jutra
  • Aplikacje jutra
  • Programowanie
  • Księga Drogi
  • Renowacja
  • Różności
  • Archiwum
  • Autor
Copyright © All rights reserved. | DarkNews by AF themes.