Java Predicate Chain

Julian | Jul 23, 2024 min read

1. Was ist ein Predicate?

Ein Predicate ist ein funktionales Interface in Java 8, das eine Bedingung prüft und einen boolean Wert zurückgibt: true oder false. Es hat eine einzige abstrakte Methode:

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

Das bedeutet, dass ein Predicate verwendet wird, um eine Bedingung auf eine Eingabe vom Typ T anzuwenden und zu prüfen, ob sie erfüllt ist.

2. Einfaches Beispiel für Predicate

Hier ein einfaches Beispiel, um zu demonstrieren, wie ein Predicate funktioniert:

Predicate<Integer> isEven = n -> n % 2 == 0; // Prüft, ob eine Zahl gerade ist

System.out.println(isEven.test(4)); // true
System.out.println(isEven.test(5)); // false

3. Predicates kombinieren

Java 8 ermöglicht es dir, Predicates zu kombinieren. Dafür gibt es drei Hauptmethoden:

  • and(): Kombiniert zwei Predicates und gibt true zurück, wenn beide Predicates true sind.
  • or(): Kombiniert zwei Predicates und gibt true zurück, wenn mindestens eines der Predicates true ist.
  • negate(): Gibt ein Predicate zurück, das das Gegenteil eines gegebenen Predicates ist.

4. Predicate chaining: AND-Beispiel

Die and() Methode erlaubt es, zwei Predicates zu kombinieren, sodass die Bedingung nur erfüllt wird, wenn beide Predicates true zurückgeben:

Predicate<Integer> isPositive = n -> n > 0;
Predicate<Integer> isEven = n -> n % 2 == 0;

Predicate<Integer> isPositiveAndEven = isPositive.and(isEven);

System.out.println(isPositiveAndEven.test(4)); // true
System.out.println(isPositiveAndEven.test(-4)); // false
System.out.println(isPositiveAndEven.test(5)); // false

5. Predicate chaining: OR-Beispiel

Die or() Methode erlaubt es, zwei Predicates zu kombinieren, sodass die Bedingung erfüllt wird, wenn mindestens eines der Predicates true zurückgibt:

Predicate<Integer> isNegative = n -> n < 0;
Predicate<Integer> isEven = n -> n % 2 == 0;

Predicate<Integer> isNegativeOrEven = isNegative.or(isEven);

System.out.println(isNegativeOrEven.test(4)); // true
System.out.println(isNegativeOrEven.test(-5)); // true
System.out.println(isNegativeOrEven.test(5)); // false

6. Predicate chaining: NEGATE-Beispiel

Die negate() Methode gibt ein Predicate zurück, das das Gegenteil eines gegebenen Predicates ist:

Predicate<Integer> isPositive = n -> n > 0;

Predicate<Integer> isNotPositive = isPositive.negate();

System.out.println(isNotPositive.test(4)); // false
System.out.println(isNotPositive.test(-4)); // true

7. Komplexere Beispiele und Anwendungen

Man kann diese Methoden kombinieren, um komplexere logische Bedingungen zu erstellen:

Predicate<String> isNotNull = Objects::nonNull;
Predicate<String> isNotEmpty = s -> !s.isEmpty();
Predicate<String> hasLengthOf5 = s -> s.length() == 5;

Predicate<String> complexPredicate = isNotNull.and(isNotEmpty).and(hasLengthOf5);

System.out.println(complexPredicate.test("Hello")); // true
System.out.println(complexPredicate.test("Hi")); // false
System.out.println(complexPredicate.test("")); // false
System.out.println(complexPredicate.test(null)); // false

8. Verwendung in Streams

Predicates sind besonders nützlich in Kombination mit Java Streams, da sie zur Filterung von Daten genutzt werden können:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, -1, -2, -3);

List<Integer> positiveNumbers = numbers.stream()
                                       .filter(isPositive)
                                       .collect(Collectors.toList());

System.out.println(positiveNumbers); // [1, 2, 3, 4, 5]

9. Best Practices

  • Leserlichkeit: Kette nur so viele Predicates wie nötig, um die Leserlichkeit deines Codes zu gewährleisten.
  • Wiederverwendbarkeit: Definiere Predicates als separate Variablen und kombiniere diese, um sie wiederverwenden zu können.
  • Debugging: Nutze aussagekräftige Namen für deine Predicates, um leichter debuggen zu können.

Mit diesen grundlegenden Kenntnissen zu Predicates und ihren Kombinationsmöglichkeiten solltest du in der Lage sein, 80% der Funktionalitäten in praktischen Anwendungen zu nutzen. Viel Erfolg beim Anwenden von Predicate Chains in deinen Projekten!