Predykat w Javie
Przeglądam kod, który używa Predicate
w Javie. Nigdy nie używałem Predicate
. Czy ktoś może mnie poprowadzić do jakiegoś tutoriala lub koncepcyjnego wyjaśnienia Predicate
i jego implementacji w Javie?
4 answers
Zakładam, że mówisz o com.google.common.base.Predicate<T>
z guawy.
Z API:
Określa wartość
true
lubfalse
dla danego wejścia. Na przykład, {[8] } może zaimplementowaćPredicate<String>
i zwrócić true dla dowolnego ciągu odpowiadającego podanemu wyrażeniu regularnemu.
Jest to zasadniczo abstrakcja OOP dla boolean
testu.
Na przykład, możesz mieć metodę pomocniczą taką jak:
static boolean isEven(int num) {
return (num % 2) == 0; // simple
}
Teraz, biorąc pod uwagę List<Integer>
, możesz przetwarzać tylko liczby parzyste takie jak:
List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
for (int number : numbers) {
if (isEven(number)) {
process(number);
}
}
Z Predicate
, test if
jest abstrakcyjny jako typ. Pozwala to na interakcję z resztą API, na przykład Iterables
, które mają wiele metod użytkowych, które zajmują Predicate
.
Tak więc możesz teraz napisać coś takiego:
Predicate<Integer> isEven = new Predicate<Integer>() {
@Override public boolean apply(Integer number) {
return (number % 2) == 0;
}
};
Iterable<Integer> evenNumbers = Iterables.filter(numbers, isEven);
for (int number : evenNumbers) {
process(number);
}
Zauważ, że teraz pętla for-each jest znacznie prostsza bez testu if
. Osiągnęliśmy wyższy poziom abtrakcji definiując Iterable<Integer> evenNumbers
, przez filter
-ING używając Predicate
.
API links
-
Iterables.filter
- zwraca elementy, które spełniają predykat.
O funkcji wyższego rzędu
Predicate
pozwala Iterables.filter
służyć jako tzw. funkcja wyższego rzędu. Sama w sobie oferuje to wiele zalet. Weźmy przykład List<Integer> numbers
powyżej. Załóżmy, że chcemy sprawdzić, czy wszystkie liczby są dodatnie. Możemy napisać coś takiego:
static boolean isAllPositive(Iterable<Integer> numbers) {
for (Integer number : numbers) {
if (number < 0) {
return false;
}
}
return true;
}
//...
if (isAllPositive(numbers)) {
System.out.println("Yep!");
}
Z Predicate
, oraz z resztą bibliotek możemy zamiast tego napisać:
Predicate<Integer> isPositive = new Predicate<Integer>() {
@Override public boolean apply(Integer number) {
return number > 0;
}
};
//...
if (Iterables.all(numbers, isPositive)) {
System.out.println("Yep!");
}
Mam nadzieję, że możesz teraz zobaczyć wartość w wyższych abstrakcjach dla procedur takich jak "filter all elements by the given predicate", "check if all elements supply the given predicate", etc make for better code.
Niestety Java nie ma metod pierwszej klasy: nie można przekazać metod do Iterables.filter
i Iterables.all
. Można oczywiście przekazywać obiekty w Javie. Tak więc typ Predicate
jest zdefiniowany, i przekazujesz obiekty implementując ten interfejs.
Zobacz też
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-11 16:50:59
Predykat jest funkcją, która zwraca wartość true / false (tj. boolean), w przeciwieństwie do twierdzenia, które jest wartością true/false (tj. boolean). 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 dostarcza klasę, która implementuje ten interfejs. Przykładem interfejsu dla predykatu może być:
public interface Predicate<ARGTYPE>
{
public boolean evaluate(ARGTYPE arg);
}
I wtedy możesz mieć taką implementację as:
public class Tautology<E> implements Predicate<E>
{
public boolean evaluate(E arg){
return true;
}
}
Aby uzyskać lepsze zrozumienie pojęciowe, warto przeczytać o logice pierwszego rzędu.
Edit
Istnieje standardowy predykat interface (java.util.funkcja.Predykat) zdefiniowany w Java API jako Java 8. Przed wersją Java 8 wygodne może być ponowne użycie com.google.pospolite.baza.Predykat interfejs z Guava.
Zauważ również, że od wersji Java 8 o wiele prostsze jest pisanie predykatów przez używając lambda. Na przykład, w Javie 8 i wyższej, można przekazać p -> true
do funkcji, zamiast definiować podklasę nazwaną Tautology, jak powyżej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-30 04:25:07
Możesz zobaczyć Przykłady java doc lub przykład użycia predykatu tutaj
Zasadniczo służy do filtrowania wierszy w zestawie wyników na podstawie dowolnych kryteriów, które możesz mieć i zwraca true dla tych wierszy, które spełniają Twoje kryteria:
// the age column to be between 7 and 10
AgeFilter filter = new AgeFilter(7, 10, 3);
// set the filter.
resultset.beforeFirst();
resultset.setFilter(filter);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-02 04:44:38
Dodając do tego co Micheal powiedział:
Możesz używać predykatu w następujący sposób w filtrowaniu kolekcji w Javie:
public static <T> Collection<T> filter(final Collection<T> target,
final Predicate<T> predicate) {
final Collection<T> result = new ArrayList<T>();
for (final T element : target) {
if (predicate.apply(element)) {
result.add(element);
}
}
return result;
}
Jednym z możliwych orzeczeń może być:
final Predicate<DisplayFieldDto> filterCriteria =
new Predicate<DisplayFieldDto>() {
public boolean apply(final DisplayFieldDto displayFieldDto) {
return displayFieldDto.isDisplay();
}
};
Użycie:
final List<DisplayFieldDto> filteredList=
(List<DisplayFieldDto>)filter(displayFieldsList, filterCriteria);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:00:27