Przechodzę przez kod, który używa Predicatew Javie. Nigdy nie używałem Predicate. Czy ktoś może poprowadzić mnie do dowolnego samouczka lub wyjaśnienia koncepcyjnego Predicatei jego implementacji w Javie?
Określa wartość truelub falsedla danego wejścia. Na przykład RegexPredicatemoże zaimplementować Predicate<String>i zwrócić wartość true dla dowolnego ciągu, który pasuje do danego wyrażenia regularnego.
Jest to w zasadzie abstrakcja OOP dla booleantestu.
Na przykład możesz mieć metodę pomocniczą, taką jak ta:
Teraz, biorąc pod uwagę a List<Integer>, możesz przetwarzać tylko liczby parzyste w ten sposób:
List<Integer> numbers =Arrays.asList(1,2,3,4,5,6,7,8,9,10);for(int number : numbers){if(isEven(number)){
process(number);}}
W Predicateprzypadku iftest jest wyodrębniany jako typ. Pozwala to na współdziałanie z resztą API, na przykład Iterables, które mają wiele metod użytkowych Predicate.
Zauważ, że teraz pętla for-each jest znacznie prostsza bez iftestu. Osiągnęliśmy wyższy poziom abtraction, definiując Iterable<Integer> evenNumbers, filterużywając -a Predicate.
Predicatepozwala Iterables.filterpełnić funkcję tzw. funkcji wyższego rzędu. Samo w sobie ma to wiele zalet. Weź List<Integer> numberspowyższy przykład. Załóżmy, że chcemy sprawdzić, czy wszystkie liczby są dodatnie. Możemy napisać coś takiego:
staticboolean isAllPositive(Iterable<Integer> numbers){for(Integer number : numbers){if(number <0){returnfalse;}}returntrue;}//...if(isAllPositive(numbers)){System.out.println("Yep!");}
Za pomocą Predicatei współpracując z pozostałymi bibliotekami możemy zamiast tego napisać:
Predicate<Integer> isPositive =newPredicate<Integer>(){@Overridepublicboolean apply(Integer number){return number >0;}};//...if(Iterables.all(numbers, isPositive)){System.out.println("Yep!");}
Miejmy nadzieję, że teraz możesz zobaczyć wartość w wyższych abstrakcji dla procedur takich jak „filtruj wszystkie elementy według podanego predykatu”, „sprawdź, czy wszystkie elementy spełniają podany predykat”, itp. Tworzą lepszy kod.
Niestety Java nie ma metod pierwszej klasy: nie można przekazywać metod do Iterables.filteri Iterables.all. Możesz oczywiście przekazywać obiekty w Javie. W ten sposób Predicatetyp jest zdefiniowany i zamiast tego przekazujesz obiekty implementujące ten interfejs.
Nie odnosiłem się do Predykatu Guawy, powinienem być jasny w moim pytaniu, ale Twoje wyjaśnienie pomogło mi zrozumieć, czego szukałem, w jaki sposób logika predykatów jest używana w Javie. Dziękuję za szczegółowe wyjaśnienie
srikanth
@polygenelubricants, Predicate<Integer>Po co wymyślać, skoro już mamy, F<Integer, Boolean>który robi dokładnie to samo?
Pacerier
Możesz to również zrobić w sposób java 8: List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); Predicate<Integer> isEven = integer -> (integer % 2) == 0; Iterable<Integer> evenNumbers = numbers.stream().filter(isEven).collect(Collectors.toList());
14
Predykat to funkcja, która zwraca wartość prawda / fałsz (tj. Wartość logiczna), w przeciwieństwie do zdania, które jest wartością prawda / fałsz (tj. Wartość logiczną). W Javie nie można mieć samodzielnych funkcji, więc tworzy się predykat, tworząc interfejs dla obiektu, który reprezentuje predykat, a następnie udostępnia klasę, która implementuje ten interfejs. Przykładem interfejsu predykatu może być:
Należy również zauważyć, że od wersji Java 8 pisanie predykatów przy użyciu lambd jest znacznie prostsze. Na przykład w Javie 8 i nowszych można przejść p -> truedo funkcji zamiast definiować nazwaną podklasę Tautology, jak powyżej.
Zasadniczo służy do filtrowania wierszy w zestawie wyników na podstawie dowolnych określonych kryteriów i zwracania wartości true dla tych wierszy, które spełniają kryteria:
// the age column to be between 7 and 10AgeFilter filter =newAgeFilter(7,10,3);// set the filter.
resultset.beforeFirst();
resultset.setFilter(filter);
Możesz użyć Predicate w następujący sposób do filtrowania kolekcji w java:
publicstatic<T>Collection<T> filter(finalCollection<T> target,finalPredicate<T> predicate){finalCollection<T> result =newArrayList<T>();for(final T element : target){if(predicate.apply(element)){
result.add(element);}}return result;}
Czy to w zasadzie nie podważa celu? Głównym powodem wyboru podejścia funkcjonalnego jest NIE iteracja ręcznie i pozbycie się for. Poziom abstrakcji staje się wyższy i potężniejszy - jednak ręczne wykonanie for mija się z tym celem i wraca do abstrakcji niskiego poziomu.
Predicate
? Coś podobnego? Coś zupełnie innego?Predicate
Odpowiedzi:
Zakładam, że mówisz o
com.google.common.base.Predicate<T>
Guava.Z API:
Jest to w zasadzie abstrakcja OOP dla
boolean
testu.Na przykład możesz mieć metodę pomocniczą, taką jak ta:
Teraz, biorąc pod uwagę a
List<Integer>
, możesz przetwarzać tylko liczby parzyste w ten sposób:W
Predicate
przypadkuif
test jest wyodrębniany jako typ. Pozwala to na współdziałanie z resztą API, na przykładIterables
, które mają wiele metod użytkowychPredicate
.Możesz więc teraz napisać coś takiego:
Zauważ, że teraz pętla for-each jest znacznie prostsza bez
if
testu. Osiągnęliśmy wyższy poziom abtraction, definiującIterable<Integer> evenNumbers
,filter
używając -aPredicate
.Linki API
Iterables.filter
Na funkcji wyższego rzędu
Predicate
pozwalaIterables.filter
pełnić funkcję tzw. funkcji wyższego rzędu. Samo w sobie ma to wiele zalet. WeźList<Integer> numbers
powyższy przykład. Załóżmy, że chcemy sprawdzić, czy wszystkie liczby są dodatnie. Możemy napisać coś takiego:Za pomocą
Predicate
i współpracując z pozostałymi bibliotekami możemy zamiast tego napisać:Miejmy nadzieję, że teraz możesz zobaczyć wartość w wyższych abstrakcji dla procedur takich jak „filtruj wszystkie elementy według podanego predykatu”, „sprawdź, czy wszystkie elementy spełniają podany predykat”, itp. Tworzą lepszy kod.
Niestety Java nie ma metod pierwszej klasy: nie można przekazywać metod do
Iterables.filter
iIterables.all
. Możesz oczywiście przekazywać obiekty w Javie. W ten sposóbPredicate
typ jest zdefiniowany i zamiast tego przekazujesz obiekty implementujące ten interfejs.Zobacz też
źródło
Predicate<Integer>
Po co wymyślać, skoro już mamy,F<Integer, Boolean>
który robi dokładnie to samo?List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); Predicate<Integer> isEven = integer -> (integer % 2) == 0; Iterable<Integer> evenNumbers = numbers.stream().filter(isEven).collect(Collectors.toList());
Predykat to funkcja, która zwraca wartość prawda / fałsz (tj. Wartość logiczna), w przeciwieństwie do zdania, które jest wartością prawda / fałsz (tj. Wartość logiczną). W Javie nie można mieć samodzielnych funkcji, więc tworzy się predykat, tworząc interfejs dla obiektu, który reprezentuje predykat, a następnie udostępnia klasę, która implementuje ten interfejs. Przykładem interfejsu predykatu może być:
A potem możesz mieć implementację taką jak:
Aby lepiej zrozumieć koncepcję, możesz przeczytać o logice pierwszego rzędu.
Edycja
Istnieje standardowy interfejs predykatu ( java.util.function.Predicate ) zdefiniowany w Java API od wersji Java 8. Przed wersją Java 8 wygodnym może być ponowne użycie interfejsu com.google.common.base.Predicate z Guawa .
Należy również zauważyć, że od wersji Java 8 pisanie predykatów przy użyciu lambd jest znacznie prostsze. Na przykład w Javie 8 i nowszych można przejść
p -> true
do funkcji zamiast definiować nazwaną podklasę Tautology, jak powyżej.źródło
Możesz zobaczyć przykłady dokumentacji java lub przykład użycia Predicate tutaj
Zasadniczo służy do filtrowania wierszy w zestawie wyników na podstawie dowolnych określonych kryteriów i zwracania wartości true dla tych wierszy, które spełniają kryteria:
źródło
Podsumowując to, co powiedział Micheal :
Możesz użyć Predicate w następujący sposób do filtrowania kolekcji w java:
jednym możliwym predykatem może być:
Stosowanie:
źródło