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?

Author: Xaerxess, 2010-06-02

4 answers

Zakładam, że mówisz o com.google.common.base.Predicate<T> z guawy.

Z API:

Określa wartość true lub false 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


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ż

 200
Author: polygenelubricants,
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.

 13
Author: Michael Aaron Safyan,
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);
 0
Author: techzen,
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);
 0
Author: jai,
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