Eine Java 8 Predicate Lambda-Schnittstelle mit Beispielen
Ein Großteil der Java-Programmierung – von bedingten Anweisungen bis zu iterativen Schleifen – beschäftigt sich mit der Auswertung von wahren oder falschen Werten. Wenn man mit den Streams-API- und Lambda-Funktionen des Java Development Kit (JDK) arbeitet, kann man die Predicate-Schnittstelle verwenden, um die Auswertung boolescher Bedingungen zu vereinfachen.
Auch bekannt als Java 8 Predicate (Prädikat) – welches aus der JDK-Version stammt, in der funktionale Programmierung eingeführt wurde – definiert diese Schnittstelle fünf Methoden, auch wenn nur die Testmethode des Java Predicate ausgewertet wird, wenn sie in einem Stream-API- oder Lambda-Aufruf zum Einsatz kommt.
Klassisches Beispiel für Java 8 Predicate
Das Java 8 Predicate ist zwar eine funktionale Schnittstelle, aber nichts hindert einen Entwickler daran, sie auf traditionelle Weise zu verwenden. Hier ist ein Java-Predicate-Beispiel, das eine neue Klasse erstellt, die das Predicate Interface erweitert, zusammen mit einer separaten Klasse, die das Predicate in seiner Hauptmethode verwendet:
import java.util.function.*;
public class Java8PredicateTutorial {
public static void main(String args[]) {
PredicateExample example = new PredicateExample();
System.out.printf("Gretzky's number is even: %s", example.test(99));
boolean value = example.test(66);
System.out.printf("\nLemieux's number is even: %s ", value);
}
}
class PredicateExample implements Predicate<Integer> {
public boolean test(Integer x) {
if (x%2==0){
return true;
} else {
return false;
}
}
}
Abbildung 2 zeigt die Ergebnisse, wenn man dieses Tutorial zur Predicate-Schnittstelle kompiliert und ausführt.
Java-Predicate als innere Klasse
Wenn man ein Entwickler ist, der innere Klassen bevorzugt, kann man das Beispiel ein wenig bereinigen und dessen Ausführlichkeit reduzieren. Das Ergebnis qualifiziert sich allerdings nicht ganz als Beispiel für funktionale Programmierung:
import java.util.function.*;
public class Java8PredicateTutorial {
public static void main(String args[]) {
Predicate predicateExample = new Predicate<Integer>() {
public boolean test(Integer x) {
return (x % 2 == 0);
}
};
System.out.printf("Gretzky's number is even: %s", predicateExample.test(99));
System.out.printf("\nLemieux's number is even: %s ", predicateExample.test(66));
}
}
Java Predicate Lambda-Beispiel
Wenn man sich über die Java 8 Predicate-Schnittstelle informiert, interessiert man sich wahrscheinlich auch dafür, wie man sie in einer Lambda-Funktion verwendet.
Das Ziel eines Lambda-Ausdrucks ist es, die Ausführlichkeit von Java-Code zu reduzieren, insbesondere in Situationen, in denen man ein Interface mit nur einer funktionalen Methode überschreiben muss. So erstellt der Code ein Java Predicate mit einem Lambda-Ausdruck:
Predicate<Integer> lambdaPredicate = (Integer x) -> (x % 2 == 0);
Im Vergleich zu traditionellen Methoden zur Interface-Erstellung sind Lambda-Ausdrücke deutlich prägnanter. Hier ist ein vollständiges Beispiel des Java Predicate, das mit einem Lambda-Ausdruck implementiert ist:
import java.util.function.*;
public class Java8PredicateTutorial {
public static void main(String args[]) {
/* Java predicate lambda example */
Predicate<Integer> lambdaPredicate = (Integer x) -> (x % 2 == 0);
System.out.printf("Gretzky's number is even: %s", lambdaPredicate.test(99));
System.out.printf("\nLemieux's number is even: %s ", lambdaPredicate.test(66));
}
}
Java Predicate und Lambda-Streams
Die Verwendung von funktionalen Ausdrücken ist seit der Veröffentlichung von JDK 8 in der gesamten Java-API vertreten. Die Streams-API verwendet Lambda-Ausdrücke und das Java Predicate, mit dem Filterausdruck als einem Beispiel.
Hier ist ein Lambda-, Stream- und Predicate-Beispiel, in dem alle geraden Zahlen aus einer Liste von ganzzahligen Objekten gezogen werden:
import java.util.function.*;
import java.util.*;
import java.util.stream.*;
public class LambdaPredicateStreamExample {
public static void main(String args[]) {
List<Integer> jerseys = Arrays.asList(99, 66, 88, 16);
/* Java predicate and lambda stream example usage */
List<Integer> evenNumbers =
jerseys.stream()
.filter( x -> ((x%2)==0))
.collect(Collectors.toList());
/* The following line prints: [66, 88, 16] 8 */
System.out.println(evenNumbers);
}
}
Wie man sieht, kann die kombinierte Verwendung von Lambda-Funktionen, Streams und der Java-Predicate-Schnittstelle sehr kompakten Code erzeugen, der ebenso leistungsfähig wie leicht zu lesen ist.