Unter der Annahme, dass ich einen zufälligen Filter in einem Stream verwende, besteht die einfachste Möglichkeit darin, das Prädikat direkt einzugeben:
%Vor%Ich kann auch einfach eine Referenz erstellen und das Prädikat im Voraus definieren:
%Vor%Aber ich kann auch eine Funktion verwenden:
%Vor%Soweit ich das beurteilen kann, ist das Prädikat natürlich viel begrenzter, während die Funktion Nebenwirkungen haben könnte. Aber da Leute wie Venkat Subramaniam die letztere Lösung verwenden, frage ich mich wirklich: Was sind die Hauptunterschiede hier?
Nein! Prädikat ist im Vergleich zu einer Methodenreferenz nicht wirklich begrenzt! In der Tat sind diese Dinge alle gleich!
Sehen Sie sich die Funktionssignatur filter()
an:
filter(Predicate<? super T> predicate)
Und lassen Sie uns Ihre Beispiele betrachten:
x.stream().filter(e -> e % 2 == 0)
Der erste ist nur eine Inline-Version des letzteren.
%Vor% und hier können Sie Method References
in Aktion sehen. MR sind nur ein syntaktischer Zucker, mit dem Sie Lambda Expression basierend auf bereits existierenden Funktionen definieren können.
Am Ende des Tages werden alle diese Ausdrücke zur gleichen Implementierung der Predicate-Funktionsschnittstelle.
Sie können in Ihren Lambda Expressions auch Nebenwirkungen mit der Block-Syntax auf der rechten Seite ausführen, aber es wird generell nicht empfohlen:
%Vor%Beim Betrachten einer Bibliothek wiederverwendbarer Prädikate ist eine Bibliothek von Funktionen, die einen booleschen Wert zurückgeben, eine weitaus vielseitigere Sammlung von Prädikaten als eine Bibliothek von statischen letzten Prädikat-Instanzen. Warum?
Betrachten Sie eine Bibliothek, die Folgendes enthält:
%Vor%gegen
%Vor%filter(MyLib::isEven)
als filter(i -> i % 2 == 0)
zu scannen und filter(MyLib::isEven)
sagt Ihnen genau, was aufgerufen wird, während filter(MyLib.IS_EVEN)
nicht MyLib.isEven(i)
scannt besser als MyLib.IS_EVEN.test(i)
IntPredicate
anstelle von Predicate<Integer>
a Guava Predicate<Integer>
, Apache Collections4 Predicate<Integer>
usw. verwenden müssen, machen Sie mit einer Bibliotheksfunktion einfach weiter MyLib::isEven
. Bei einer static final Predicate<Integer>
-Instanz müssten Sie sie konvertieren, indem Sie MyLib.IS_EVEN::test
ausführen (und am Ende verwenden Sie trotzdem eine Methodenreferenz) Dasselbe gilt für alle funktionalen Typen. Funktionen schreiben. Sie können mit einer einfachen Methodenreferenz auf jeden Funktionstyp angewendet werden, der der Signatur entspricht.
Tags und Links java-8 java-stream predicate