Sto esaminando il codice che utilizza Predicate
in Java. Non l'ho mai usato Predicate
. Qualcuno può guidarmi a qualsiasi tutorial o spiegazione concettuale Predicate
e alla sua implementazione in Java?
Predicate
Sto esaminando il codice che utilizza Predicate
in Java. Non l'ho mai usato Predicate
. Qualcuno può guidarmi a qualsiasi tutorial o spiegazione concettuale Predicate
e alla sua implementazione in Java?
Predicate
Risposte:
Presumo tu stia parlando di com.google.common.base.Predicate<T>
Guava.
Dall'API:
Determina un valore
true
ofalse
per un dato input. Ad esempio, aRegexPredicate
potrebbe implementarePredicate<String>
e restituire true per qualsiasi stringa che corrisponde alla sua espressione regolare data.
Questa è essenzialmente un'astrazione OOP per un boolean
test.
Ad esempio, potresti avere un metodo di supporto come questo:
static boolean isEven(int num) {
return (num % 2) == 0; // simple
}
Ora, dato un List<Integer>
, puoi elaborare solo i numeri pari in questo modo:
List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
for (int number : numbers) {
if (isEven(number)) {
process(number);
}
}
Con Predicate
, il if
test viene estratto come un tipo. Ciò gli consente di interagire con il resto dell'API, ad esempioIterables
, che ha molti metodi di utilità che accettano Predicate
.
Quindi, ora puoi scrivere qualcosa del genere:
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);
}
Nota che ora il ciclo for-each è molto più semplice senza il if
test. Abbiamo raggiunto un livello più alto di astrazione definendo Iterable<Integer> evenNumbers
, filter
utilizzando un Predicate
.
Iterables.filter
Predicate
permette Iterables.filter
di servire come quella che viene chiamata una funzione di ordine superiore. Di per sé, questo offre molti vantaggi. Prendi l' List<Integer> numbers
esempio sopra. Supponiamo di voler verificare se tutti i numeri sono positivi. Possiamo scrivere qualcosa del genere:
static boolean isAllPositive(Iterable<Integer> numbers) {
for (Integer number : numbers) {
if (number < 0) {
return false;
}
}
return true;
}
//...
if (isAllPositive(numbers)) {
System.out.println("Yep!");
}
Con un Predicate
, e interagendo con il resto delle librerie, possiamo invece scrivere questo:
Predicate<Integer> isPositive = new Predicate<Integer>() {
@Override public boolean apply(Integer number) {
return number > 0;
}
};
//...
if (Iterables.all(numbers, isPositive)) {
System.out.println("Yep!");
}
Si spera che ora tu possa vedere il valore in astrazioni più alte per routine come "filtra tutti gli elementi in base al predicato dato", "controlla se tutti gli elementi soddisfano il predicato dato", ecc. Per ottenere un codice migliore.
Sfortunatamente Java non ha metodi di prima classe: non puoi passare metodi a Iterables.filter
e Iterables.all
. Puoi, ovviamente, passare oggetti in Java. Pertanto, il Predicate
tipo viene definito e si passano invece oggetti che implementano questa interfaccia.
Predicate<Integer>
quando abbiamo già F<Integer, Boolean>
che fa esattamente la stessa cosa?
Un predicato è una funzione che restituisce un valore vero / falso (cioè booleano), al contrario di una proposizione che è un valore vero / falso (cioè booleano). In Java, non è possibile avere funzioni autonome, quindi si crea un predicato creando un'interfaccia per un oggetto che rappresenta un predicato e quindi si fornisce una classe che implementa tale interfaccia. Un esempio di interfaccia per un predicato potrebbe essere:
public interface Predicate<ARGTYPE>
{
public boolean evaluate(ARGTYPE arg);
}
E poi potresti avere un'implementazione come:
public class Tautology<E> implements Predicate<E>
{
public boolean evaluate(E arg){
return true;
}
}
Per ottenere una migliore comprensione concettuale, potresti voler leggere la logica del primo ordine.
Modifica
Esiste un'interfaccia Predicate standard ( java.util.function.Predicate ) definita nell'API Java a partire da Java 8. Prima di Java 8, potresti trovare conveniente riutilizzare l' interfaccia com.google.common.base.Predicate da Guava .
Inoltre, si noti che a partire da Java 8, è molto più semplice scrivere predicati utilizzando lambda. Ad esempio, in Java 8 e versioni successive, è possibile passare p -> true
a una funzione invece di definire una sottoclasse Tautology denominata come sopra.
È possibile visualizzare gli esempi di documentazione java o l'esempio di utilizzo di Predicate qui
Fondamentalmente viene utilizzato per filtrare le righe nel gruppo di risultati in base a criteri specifici che potresti avere e restituire true per quelle righe che soddisfano i tuoi criteri:
// the age column to be between 7 and 10
AgeFilter filter = new AgeFilter(7, 10, 3);
// set the filter.
resultset.beforeFirst();
resultset.setFilter(filter);
In aggiunta a quanto ha detto Micheal :
È possibile utilizzare Predicate come segue per filtrare le raccolte in java:
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;
}
un possibile predicato può essere:
final Predicate<DisplayFieldDto> filterCriteria =
new Predicate<DisplayFieldDto>() {
public boolean apply(final DisplayFieldDto displayFieldDto) {
return displayFieldDto.isDisplay();
}
};
Uso:
final List<DisplayFieldDto> filteredList=
(List<DisplayFieldDto>)filter(displayFieldsList, filterCriteria);
Predicate
? Qualcosa di simile? Qualcos'altro completamente?