Je suis en train de parcourir le code qui utilise Predicate
en Java. Je n'ai jamais utilisé Predicate
. Quelqu'un peut-il me guider vers une explication théorique ou conceptuelle de Predicate
et de son implémentation en Java?
Je suppose que vous parlez de com.google.common.base.Predicate<T>
de Guava.
De l'API:
Détermine une valeur
true
oufalse
pour une entrée donnée. Par exemple, unRegexPredicate
peut implémenterPredicate<String>
Et renvoyer true pour toute chaîne correspondant à son expression régulière donnée.
Il s’agit essentiellement d’une abstraction OOP pour un test boolean
.
Par exemple, vous pouvez avoir une méthode d'assistance comme celle-ci:
static boolean isEven(int num) {
return (num % 2) == 0; // simple
}
Maintenant, étant donné un List<Integer>
, Vous ne pouvez traiter que les nombres pairs comme ceci:
List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
for (int number : numbers) {
if (isEven(number)) {
process(number);
}
}
Avec Predicate
, le test if
est résumé sous forme de type. Cela lui permet d'interagir avec le reste de l'API, tel que Iterables
, qui ont de nombreuses méthodes utilitaires prenant Predicate
.
Ainsi, vous pouvez maintenant écrire quelque chose comme ceci:
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);
}
Notez que maintenant la boucle for-each est beaucoup plus simple sans le test if
. Nous avons atteint un niveau d'absorption plus élevé en définissant Iterable<Integer> evenNumbers
, En filter
- ing en utilisant un Predicate
.
Iterables.filter
Predicate
permet à Iterables.filter
De servir de fonction dite supérieure. À lui seul, cela offre de nombreux avantages. Prenez l'exemple List<Integer> numbers
Ci-dessus. Supposons que nous voulions vérifier si tous les nombres sont positifs. Nous pouvons écrire quelque chose comme ceci:
static boolean isAllPositive(Iterable<Integer> numbers) {
for (Integer number : numbers) {
if (number < 0) {
return false;
}
}
return true;
}
//...
if (isAllPositive(numbers)) {
System.out.println("Yep!");
}
Avec un Predicate
, et en interopérabilité avec le reste des bibliothèques, nous pouvons plutôt écrire ceci:
Predicate<Integer> isPositive = new Predicate<Integer>() {
@Override public boolean apply(Integer number) {
return number > 0;
}
};
//...
if (Iterables.all(numbers, isPositive)) {
System.out.println("Yep!");
}
Espérons que vous pouvez maintenant voir la valeur dans des abstractions plus élevées pour des routines telles que "filtrer tous les éléments par le prédicat donné", "vérifier si tous les éléments satisfont le prédicat donné", etc. créent un meilleur code.
Malheureusement, Java ne dispose pas de méthodes de première classe: vous ne pouvez pas transmettre les méthodes à Iterables.filter
Et Iterables.all
. Vous pouvez, bien sûr, passer des objets en Java. Ainsi, le type Predicate
est défini et vous transmettez des objets en implémentant cette interface.
Un prédicat est une fonction qui renvoie une valeur true/false (c'est-à-dire boolean), par opposition à une proposition qui est une valeur true/false (c'est-à-dire boolean). En Java, on ne peut pas avoir de fonctions autonomes. On crée donc un prédicat en créant une interface pour un objet qui représente un prédicat, puis on fournit une classe qui implémente cette interface. Un exemple d'interface pour un prédicat pourrait être:
public interface Predicate<ARGTYPE>
{
public boolean evaluate(ARGTYPE arg);
}
Et puis vous pourriez avoir une implémentation telle que:
public class Tautology<E> implements Predicate<E>
{
public boolean evaluate(E arg){
return true;
}
}
Pour une meilleure compréhension conceptuelle, vous voudrez peut-être vous renseigner sur la logique du premier ordre.
Modifier
Il existe une interface Predicate ( Java.util.function.Predicate ) standard définie dans la Java du Java 8. Avant Java 8, il peut être pratique de réutiliser les com.google.common.base.Predicate = interface de Guava .
Notez également qu'à partir de Java 8, il est beaucoup plus simple d'écrire des prédicats à l'aide de lambdas. Par exemple, dans Java 8 et supérieur, vous pouvez passer p -> true
à une fonction au lieu de définir une sous-classe nommée Tautology comme ci-dessus.
Vous pouvez voir les exemples doc Java ou l'exemple d'utilisation de Predicate ici
Fondamentalement, il est utilisé pour filtrer les lignes du jeu de résultats en fonction de tout critère spécifique que vous pouvez avoir et renvoyer true pour les lignes qui répondent à vos critères:
// the age column to be between 7 and 10
AgeFilter filter = new AgeFilter(7, 10, 3);
// set the filter.
resultset.beforeFirst();
resultset.setFilter(filter);
Ajouter à ce que Michael a dit:
Vous pouvez utiliser Predicate comme suit pour filtrer des collections en 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 prédicat possible peut être:
final Predicate<DisplayFieldDto> filterCriteria =
new Predicate<DisplayFieldDto>() {
public boolean apply(final DisplayFieldDto displayFieldDto) {
return displayFieldDto.isDisplay();
}
};
Usage:
final List<DisplayFieldDto> filteredList=
(List<DisplayFieldDto>)filter(displayFieldsList, filterCriteria);