Je suis en train de parcourir le code qui utilise Predicate
en Java. Je ne l'ai jamais utilisé Predicate
. Quelqu'un peut-il me guider vers un didacticiel ou une explication conceptuelle Predicate
et sa mise en œuvre en Java?
Predicate
Je suis en train de parcourir le code qui utilise Predicate
en Java. Je ne l'ai jamais utilisé Predicate
. Quelqu'un peut-il me guider vers un didacticiel ou une explication conceptuelle Predicate
et sa mise en œuvre en Java?
Predicate
Réponses:
Je suppose que vous parlez com.google.common.base.Predicate<T>
de Guava.
Depuis l'API:
Détermine une valeur
true
oufalse
pour une entrée donnée. Par exemple, aRegexPredicate
pourrait implémenterPredicate<String>
et retourner true pour toute chaîne qui correspond à son expression régulière donnée.
Il s'agit essentiellement d'une abstraction POO pour un boolean
test.
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é a 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 if
test est extrait en tant que type. Cela lui permet d'interagir avec le reste de l'API, par exemple Iterables
, qui a de nombreuses méthodes utilitaires qui prennentPredicate
.
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 if
test. Nous avons atteint un niveau d'abtraction plus élevé en définissant Iterable<Integer> evenNumbers
, en filter
utilisant un Predicate
.
Iterables.filter
Predicate
permet Iterables.filter
de servir de ce qu'on appelle une fonction d'ordre supérieur. En soi, cela présente de nombreux avantages. Prenons l' List<Integer> numbers
exemple ci-dessus. Supposons que nous voulions tester 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 a Predicate
, et en interopérant avec le reste des bibliothèques, nous pouvons à la place é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!");
}
J'espère que vous pouvez maintenant voir la valeur dans des abstractions plus élevées pour des routines comme "filtrer tous les éléments par le prédicat donné", "vérifier si tous les éléments satisfont au prédicat donné", etc. pour un meilleur code.
Malheureusement, Java n'a pas de méthodes de première classe: vous ne pouvez pas passer de méthodes à Iterables.filter
et Iterables.all
. Vous pouvez bien sûr faire circuler des objets en Java. Ainsi, le Predicate
type est défini et vous passez des objets implémentant cette interface à la place.
Predicate<Integer>
quand on a déjà F<Integer, Boolean>
qui fait exactement la même chose?
Un prédicat est une fonction qui renvoie une valeur vrai / faux (c'est-à-dire booléenne), par opposition à une proposition qui est une valeur vrai / faux (c'est-à-dire booléenne). En Java, on ne peut pas avoir de fonctions autonomes, et donc on crée un prédicat en créant une interface pour un objet qui représente un prédicat et on fournit ensuite 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 obtenir une meilleure compréhension conceptuelle, vous voudrez peut-être en savoir plus sur la logique du premier ordre.
Edit
Il existe une interface Predicate standard ( 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 depuis Goyave .
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, on peut passer p -> true
à une fonction au lieu de définir une sous-classe Tautology nommée comme ci-dessus.
Vous pouvez voir les exemples de documentation java ou l'exemple d'utilisation de Predicate ici
Fondamentalement, il est utilisé pour filtrer les lignes de l'ensemble de résultats en fonction de tous les critères spécifiques 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);
Ajoutant à ce que Micheal a dit:
Vous pouvez utiliser Predicate comme suit pour filtrer les 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);
Predicate
? Quelque chose de similaire? Quelque chose de complètement différent?