W tym artykule, bierzemy pod lupę pojęcie predykatu. W języku Java, jest taki cosik o nazwie "Predicate" w postaci jednego z wielu występujących interfejsów funkcyjnych. I właśnie ten temat dzisiaj atakujemy ⚔!
CO W SOBIE KRYJE "PREDICATE" W JĘZYKU JAVA?
Napisałem o "Consumer", było o "Function", to teraz jest "Predicate". "Predicate" także należy do rodziny interfejsów funkcyjnych, aczkolwiek korzystamy z niego inaczej, niż dwa wyżej wymienione.
Predykat ma za zadanie zwrócić wartość logiczną ("boolean") na podstawie podanego parametru typu T (typu generycznego). Możemy określić to po prostu "testem" czy parametr przejdzie przez niego pozytywnie, czy nie.
Do czego to się może przydać? Na przykład do filtrowania kolekcji! Metoda "filter" omawiana jakiś czas temu jako parametru, oczekuje właśnie predykatu jako parametru, dzięki czemu zawdzięcza swoją uniwersalność 💯. Nie ma znaczenia czy jest to kolekcja liczb całkowitych i chcemy wyodrębnić liczby podzielne przez 5, czy to kolekcja obiektów przeciwników i chcemy odsunąć na bok tych, którzy stoją od gracza powyżej 100 metrów. To jest "biceps" predykatu 💪!
Przypomnę jakie występują interfejsy funkcyjne, które stosujemy najczęściej jako wyrażenia lambda w miejsce parametrów formalnych metod:
- "Consumer" (metoda typu "void" przyjmująca jeden parametr),
- "Function" (metoda zwracająca wartość i przyjmująca jeden parametr),
- "Predicate" (wyrażenie zwracające wartość logiczną przyjmujące jeden parametr) 👈 tu Pan(i) jesteś 😁,
- "Supplier" (metoda zwracająca wartość i nieprzyjmująca żadnych parametrów).
Przykład kodu źródłowego
Przeszliśmy przez teorię, teraz praktyka opatrzona przykładem 🙂. Mamy metodę, do której chcemy umieścić "Predicate" w języku Java:
public void doSomething() {
}Sam parametr predykatu może przyjąć taką postać:
public void doSomething(Predicate predicate) W miejsce nawiasów kątowych wstawiamy typ parametru, którego będziemy klasyfikować czy "zdaje egzamin", czy nie. Ja dałem liczbę całkowitą, czyli "Integer" (dla typów prostych dajemy nazwę klasy opakowującej!).
Dajmy prostą definicję metody i przejdźmy do przykładowych wywołań:
public void doSomething(int integer, Predicate predicate) {
if(predicate != null) {
System.out.println("Wynik działania predykatu: " + predicate.test(integer));
}
} Predykat może przyjąć wartość "null", stąd otaczamy wywołanie metody ("test") instrukcją warunkową na taką okoliczność. Nie chcemy robić wyjątków, w innym znaczeniu tego słowa 😆.
A teraz pytanie: jak mogą wyglądać definicje w miejsce predykatu w chwili, gdy wywołujemy metodę? Oto przykład:
doSomething(55, integer -> integer % 2 == 0);Sprawdzenie czy liczba 55 jest parzysta 😄. A to dużo bardziej rozbudowany przykład 😱:
launcher.doSomething(17, integer -> {
if(integer <= 1) {
return false;
}
for (var i = 2; i <= Math.sqrt(integer); ++i) {
if(integer % i == 0) {
return false;
}
}
return true;
});Sprawdzenie czy liczba 17 jest liczbą pierwszą. Widać już wyraźnie co nam daje "Predicate" w języku Java. Nie tylko mamy możliwość wstawiania liczby całkowitej jaką chcemy, lecz także zdefiniować jaki test ma mieć dana liczba!
Gdy będziesz mieć dylemat który z interfejsów funkcyjnych zastosować, to spójrz na tę poradę. Predykat stosuj wtedy, gdy chcesz zaimplementować do metody "dysk zamienny" w postaci wyrażenia logicznego, który podczas wywołania metody można będzie podstawić pod swoje potrzeby, a wynik ma mieć wpływ na resztę funkcjonowania metody w jej środku.
![]() |
"Predicate" to interfejs funkcyjny pozwalający na "wymienne" wstawianie wyrażenia zwracającego wartość logiczną, które pełni funkcję "testu" dla danego elementu, dzięki czemu może wpływać na ostateczny rezultat metody.
Zakończyliśmy wątek interfejsu "Predicate" w języku Java! Mam nadzieję, że czujesz się nieco bogatszy o nową wiedzę 🧠!
NASTĘPNY ARTYKUŁ: Supplier w języku Java. Funkcja jako parametr metody
