Dalszy ciąg o interfejsach funkcyjnych jakie znajdziesz w języku Java i teraz przyszedł czas na "Function". Zapraszam!
"FUNCTION" W JĘZYKU JAVA, TYM RAZEM W ROLI INTERFEJSU FUNKCYJNEGO
Mimo znajomego słowa kluczowego, to nie tak jak myślisz, programisto 😄. Funkcję omówiliśmy sobie już dawno, a teraz skieruję Twoje oczy na coś zupełnie innego 😳.
"Function" (pisane wielką literą) to jeden z interfejsów funkcyjnych jaki możesz osadzić w miejsce parametru metody, tej powiedzmy, "klasycznej" 😉. Działa jak w pewnym sensie "dysk wymienny", który wkładasz do urządzenia, ono uruchamia zapisane w nim instrukcje, a one same mogą być za każdym razem inne 💾. Nie muszę podkreślać jak znacząco podnosi elastyczność Twojego kodu sprawiając, że za każdym wywołaniem takiej metody, możesz wstawić różne instrukcje 🤩.
Jest parę innych interfejsów, z których możesz skorzystać w zależności od tego, jakiej potrzebujesz "kombinacji" 👇:
- "Consumer" (metoda typu "void" przyjmująca jeden parametr),
- "Function" (metoda zwracająca wartość i przyjmująca jeden parametr) 👈 jesteśmy tu 😁,
- "Predicate" (wyrażenie zwracające wartość logiczną przyjmujące jeden parametr),
- "Supplier" (metoda zwracająca wartość i nieprzyjmująca żadnych parametrów).
W tym artykule opisuję drugi rodzaj, więc już wiesz kiedy najlepiej użyć słowa "Function" 😄 - kiedy chcesz, żeby wyrażenie lambda zwracało wartość oraz przyjmowało parametr. Zarówno typ parametru, jak i zwracanej wartości, może być dowolny. Dzięki wpleceniu typów generycznych, jesteś w stanie przypisać dowolne niezwiązane ze sobą typy danych!
Przykład kodu źródłowego
Spójrz na proste użycie w kodzie źródłowym. Dysponując taką metodą:
public void doSomething() {
}masz prawo wstawić parametr typu "Function", który posiada dwa "gniazda" w nawiasach kątowych. Pierwszy typ dotyczy typu parametru wejściowego, a drugi, typ wartości wynikowej jaka zostanie zwrócona na wyjściu:
public void doSomething(Function function) Na potrzeby przykładu dorzucimy dodatkowy parametr formalny w postaci łańcucha znaków:
public void doSomething(String string, Function function) {
if(function != null) {
System.out.println("Wynik działania funkcji: " + function.apply(string));
}
} "apply" jest metodą "odpalającą" nasze "Function" w języku Java - jest to jedyna metoda jaką udostępnia, stąd jest interfejsem funkcyjnym. Zwróć uwagę, że mimo tego, że "Function" zwraca wartość, to nasza metoda jest cały czas typu "void". Może być też każdego innego typu albo przyjmować ten sam, jaki przyjmuje miejsce na wyrażenie lambda! One działają niezależnie ℹ️!
Dorzucam dwa przykładowe wywołania takiej metody z funkcją jako wyrażenie lambda:
doSomething("Mój łańcuch znaków", String::length);Tu, jednym zdaniem: wrzucamy łańcuch znaków, a w wyrażeniu lambda będzie zwrot wartości z metody "length", czyli policzenie znaków jakie się w nim znajdują (łącznie z białymi znakami!). Ponieważ zgadza się typ parametru i zwracanej wartości, sięgnąłem po referencję do metody, aby jeszcze bardziej uściślić kod. A tu jest dużo większy przykład:
doSomething("My sweet string", string -> {
var numberOfFoundCharacters = 0;
var arrayOfCharacters = string.toCharArray();
for (var character : arrayOfCharacters) {
if(character == 'e') {
++numberOfFoundCharacters;
}
}
return numberOfFoundCharacters;
});To wyrażenie lambda odpowiada za wyznaczenie ile literek 'e' znajduje się w podanym przez nas łańcuchu. Można użyć też tego zapisu 👇:
doSomething("My sweet string", string -> string.chars().mapToObj(integer -> (char)integer).toList().stream().filter(character -> character == 'e').toList().size());natomiast uznałem je za zbyt skomplikowane jak na artykuł dla tych, którzy stawiają pierwszy krok w tym temacie 😅.
Dla osób, które zastanawiają się: "O jejku, jest tyle tych interfejsów. Skąd mam wiedzieć, który z nich wybrać i w jakiej sytuacji?" - "Function" stosuj, gdy potrzebujesz jednocześnie: wprowadzić parametr i zwrócić wartość.
![]() |
Interfejs funkcyjny "Function" pozwala na wstawienie wyrażenia lambda w miejsce parametru innej metody oczekując zarówno parametru formalnego, jak i zwrócenia na końcu wartości.
Mamy odbębniony kolejny temat 🥁!
NASTĘPNY ARTYKUŁ: Predicate w języku Java. Predykat jako parametr metody
