Je suis en train d'analyser le code qui utilise Predicate
en Java. Je n'ai jamais utilisé Predicate
. Est-ce que quelqu'un pourrait me guider vers un tutoriel ou une explication conceptuelle de Predicate
et de son implémentation en Java ?
Réponses
Trop de publicités?Je suppose que vous parlez de com.google.common.base.Predicate
de Guava.
Depuis l'API:
Détermine une valeur
true
oufalse
pour une entrée donnée. Par exemple, unRegexPredicate
pourrait implémenterPredicate
, et renvoyer vrai pour toute chaîne qui correspond à 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'aide comme ceci:
static boolean isEven(int num) {
return (num % 2) == 0; // simple
}
Maintenant, étant donné une List
, vous pouvez traiter uniquement les nombres pairs comme ceci:
List 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 abstrait en tant que type. Cela lui permet d'interagir avec le reste de l'API, comme Iterables
, qui comporte de nombreuses méthodes utilitaires prenant Predicate
.
Ainsi, vous pouvez maintenant écrire quelque chose comme ceci:
Predicate isEven = new Predicate() {
@Override public boolean apply(Integer number) {
return (number % 2) == 0;
}
};
Iterable evenNumbers = Iterables.filter(numbers, isEven);
for (int number : evenNumbers) {
process(number);
}
Remarquez que maintenant la boucle for-each est beaucoup plus simple sans le test if
. Nous avons atteint un niveau supérieur d'abstraction en définissant Iterable evenNumbers
, en filter
utilisant un Predicate
.
Liens d'API
Iterables.filter
- Renvoie les éléments qui satisfont un prédicat.
Sur les fonctions d'ordre supérieur
Predicate
permet à Iterables.filter
de servir de ce qu'on appelle une fonction d'ordre supérieur. À lui seul, cela offre de nombreux avantages. Prenez l'exemple de List 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 numbers) {
for (Integer number : numbers) {
if (number < 0) {
return false;
}
}
return true;
}
//...
if (isAllPositive(numbers)) {
System.out.println("Yep!");
}
Avec un Predicate
, et en interagissant avec le reste des bibliothèques, nous pouvons plutôt écrire ceci:
Predicate isPositive = new Predicate() {
@Override public boolean apply(Integer number) {
return number > 0;
}
};
//...
if (Iterables.all(numbers, isPositive)) {
System.out.println("Yep!");
}
Vous pouvez maintenant voir la valeur des abstractions supérieures pour les routines comme "filtrer tous les éléments par le prédicat donné", "vérifier si tous les éléments satisfont le prédicat donné", etc font pour un meilleur code.
Malheureusement, Java n'a pas de méthodes de première classe : vous ne pouvez pas passer des 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 passez des objets implémentant cette interface à la place.
Voir aussi
Un prédicat est une fonction qui renvoie une valeur true/false (c'est-à-dire booléenne), par opposition à une proposition qui est une valeur true/false (c'est-à-dire booléenne). 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
{
public boolean evaluate(ARGTYPE arg);
}
Ensuite, vous pourriez avoir une implémentation comme :
public class Tautology implements Predicate
{
public boolean evaluate(E arg){
return true;
}
}
Pour obtenir une meilleure compréhension conceptuelle, vous voudrez peut-être lire sur la logique du premier ordre.
Edit
Il existe une interface standard Predicate (java.util.function.Predicate) définie dans l'API Java à partir de Java 8. Avant Java 8, vous pouvez trouver pratique de réutiliser l'interface com.google.common.base.Predicate de Guava.
Remarquez également qu'à partir de Java 8, il est beaucoup plus simple d'écrire des prédicats en utilisant des lambdas. Par exemple, en Java 8 et plus récent, on peut passer p -> true
à une fonction au lieu de définir une sous-classe Tautology nommée comme ci-dessus.
Vous pouvez consulter les exemples de documentation Java ou l'exemple d'utilisation de Predicate ici
Essentiellement, il est utilisé pour filtrer les lignes dans le resultset en fonction de critères spécifiques que vous pouvez avoir et renvoyer true pour les lignes qui répondent à vos critères:
// la colonne d'âge doit être comprise entre 7 et 10
AgeFilter filter = new AgeFilter(7, 10, 3);
// définir le filtre.
resultset.beforeFirst();
resultset.setFilter(filter);
Ajoutant à ce que Micheal a dit:
Vous pouvez utiliser Predicate comme suit pour filtrer des collections en java:
public static Collection filter(final Collection target,
final Predicate predicate) {
final Collection result = new ArrayList();
for (final T element : target) {
if (predicate.apply(element)) {
result.add(element);
}
}
return result;
}
Un prédicat possible peut être:
final Predicate filterCriteria =
new Predicate() {
public boolean apply(final DisplayFieldDto displayFieldDto) {
return displayFieldDto.isDisplay();
}
};
Utilisation:
final List filteredList=
(List)filter(displayFieldsList, filterCriteria);