Comment faire un Prédicat à partir d'une liste personnalisée de Prédicats en Java?


Je suis relativement nouveau dans la programmation et je me demande depuis deux jours comment faire un prédicat qui est fait à partir d'une liste personnalisée d'autres prédicats. J'ai donc trouvé une sorte de solution. Voici un extrait de code qui devrait vous donner une idée. Parce que je l'ai écrit en me basant uniquement sur la lecture de diverses documentations, j'ai deux questions: 1 / est-ce une bonne solution? 2 / existe-t-il une autre solution recommandée à ce problème?

public class Tester {
  private static ArrayList<Predicate<String>> testerList;

  //some Predicates of type String here...

  public static void addPredicate(Predicate<String> newPredicate) {
    if (testerList == null) 
                 {testerList = new ArrayList<Predicate<String>>();}
    testerList.add(newPredicate);
  }

  public static Predicate<String> customTesters () {
    return s -> testerList.stream().allMatch(t -> t.test(s));

  }
}
Author: Stefan Zobel, 2017-05-27

2 answers

Vous pourriez avoir une méthode statique qui reçoit de nombreux prédicats et renvoie le prédicat que vous voulez:

public static <T> Predicate<T> and(Predicate<T>... predicates) {
    // TODO Handle case when argument is null or empty or has only one element
    return s -> Arrays.stream(predicates).allMatch(t -> t.test(s));
}

Une variante:

public static <T> Predicate<T> and(Predicate<T>... predicates) {
    // TODO Handle case when argument is null or empty or has only one element
    return Arrays.stream(predicates).reduce(t -> true, Predicate::and);
}

Ici j'utilise Stream.reduce, qui prend l'identité et un opérateur comme arguments. Stream.reduce applique l'opérateur Predicate::and à tous les éléments du flux pour produire un prédicat de résultat, et utilise l'identité pour opérer sur le premier élément du flux. C'est pourquoi j'ai utilisé t -> true comme identité, sinon le prédicat de résultat pourrait finir évaluation à false.

Utilisation:

Predicate<String> predicate = and(s -> s.startsWith("a"), s -> s.length() > 4);
 5
Author: Federico Peralta Schaffner, 2017-05-27 22:33:24

Le prédicat Java a une belle fonction de et qui renvoie un nouveau prédicat qui est l'évaluation des deux prédicats. Vous pouvez les ajouter tous en un seul avec cela.

Https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html#and-java.util.function.Predicate-

Exemple :

Predicate<String> a = str -> str != null;
Predicate<String> b = str -> str.length() != 0;
Predicate<String> c = a.and(b);

c.test("Str");
//stupid test but you see the idea :)
 1
Author: Emil Hotkowski, 2017-05-26 21:53:20