Google Guava hat ein Prädikat, das immer zurückgibttrue
. Hat Java 8 etwas Ähnliches Predicate
? Ich weiß, ich könnte es gebrauchen (foo)->{return true;}
, aber ich möchte etwas Vorgefertigtes, analog zu Collections.emptySet()
.
Google Guava hat ein Prädikat, das immer zurückgibttrue
. Hat Java 8 etwas Ähnliches Predicate
? Ich weiß, ich könnte es gebrauchen (foo)->{return true;}
, aber ich möchte etwas Vorgefertigtes, analog zu Collections.emptySet()
.
Antworten:
In Java 8 gibt es keine integrierten Prädikate für immer wahr und immer falsch. Die präziseste Art, diese zu schreiben, ist
x -> true
und
x -> false
Vergleichen Sie diese mit
Predicates.alwaysTrue() // Guava
und schließlich zu einer anonymen inneren Klasse:
new Predicate<Object>() {
public boolean test(Object x) {
return true;
}
}
Wahrscheinlich liegt der Grund dafür, dass Guava über diese integrierten Prädikate verfügt, darin, dass ein statischer Methodenaufruf einen großen syntaktischen Vorteil gegenüber einer anonymen inneren Klasse bietet. In Java 8 ist die Lambda-Syntax so präzise, dass das Schreiben eines statischen Methodenaufrufs einen syntaktischen Nachteil hat .
Das ist jedoch nur ein syntaktischer Vergleich. Es gibt wahrscheinlich einen kleinen Platzvorteil, wenn es ein einzelnes globales immer wahres Prädikat gäbe, verglichen mit x -> true
Vorkommen, die über mehrere Klassen verteilt sind, von denen jede ihre eigene Prädikatinstanz erstellen würde. Ist es das, worüber Sie sich Sorgen machen? Die Einsparungen schienen nicht zwingend zu sein, weshalb sie wahrscheinlich überhaupt nicht hinzugefügt wurden. Aber es könnte für eine zukünftige Veröffentlichung überdacht werden.
UPDATE 24.04.2015
Wir haben die Hinzufügung einer Vielzahl von statischen, benannten Funktionen in Betracht gezogen, wie z Predicate.alwaysTrue
.Runnable.noop
usw., und wir haben beschlossen , nicht mehr in zukünftigen Versionen von Java SE hinzuzufügen.
Sicherlich hat etwas, das einen Namen hat, einen Wert gegenüber einem ausgeschriebenen Lambda, aber dieser Wert ist ziemlich klein. Wir gehen davon aus, dass die Menschen lernen , wie man lesen und schreiben x -> true
und () -> { }
und dass ihre Nutzung wird sich idiomatisch. Sogar der Wert von Function.identity()
überx -> x
ist fraglich.
Es ist ein winziger Leistungsvorteil, eine vorhandene Funktion wiederzuverwenden, anstatt ein ausgeschriebenes Lambda auszuwerten. Wir erwarten jedoch, dass die Verwendung dieser Art von Funktionen so gering ist, dass ein solcher Vorteil vernachlässigbar wäre und die API-Aufblähung sicherlich nicht wert wäre.
Holger erwähnte in Kommentaren auch die Möglichkeit, zusammengesetzte Funktionen wie Predicate.or
und so zu optimieren . Dies wurde ebenfalls berücksichtigt ( JDK-8067971) ), wurde jedoch als etwas fragil und fehleranfällig eingestuft und trat selten genug auf, dass sich die Implementierung nicht lohnte.
Siehe auch diesen Lambda-FAQ- Eintrag.
Predicate.alwaysTrue()
dir könnte man es auch vermasseln , indem man versehentlich schreibt Predicate.alwaysFalse()
.
alwaysTrue()
und alwaysFalse()
. Mit dem tatsächlichen Lambda habe ich viele Variationen; Ich rekonstruiere im Wesentlichen jedes Mal die Formel. Im Wesentlichen alwaysTrue()
ist eine semantische Bezeichnung für das, was ich tun möchte; x->true
macht es tatsächlich jedes Mal wieder. Nicht riesig, aber eine Überlegung.
Predicate.alwaysTrue()
und Predicate.alwaysFalse()
Instanzen ist, dass sie durch die Kombination von Methoden , wie erkannt werden können Predicate.or
, Predicate.and
und Predicate.negate()
. Dies würde es ermöglichen, Predicate
Variablen vorab zu initialisieren alwaysTrue()
und Prädikate hinzuzufügen, indem über and
ohne Overhead kombiniert wird . Da Lambda-Ausdrücke keine Garantie für die Objektidentität haben, kann dies fehlschlagen x->true
. Übrigens, wenn ich eine Klasse X
mit einer static
Methode habe y(){return true;}
, ist die Verwendung X::y
noch kürzer als x->true
aber nicht wirklich zu empfehlen ...
x -> true
hat den Nachteil, dass ich eine Variable ohne Verwendung verwenden muss. Dies führt zu unnötiger Gehirnlast und einer Warnung in meiner IDE. Ich habe versucht zu verwenden _ -> true
, aber das ist ein Syntaxfehler. In Java fehlt definitiv ein Schlüsselwort (sprich: Keyletter) für "unbenutzte Parameter". Hoffe, dass so etwas in Java 9 kommt (oder zumindest: Java was auch immer, bevor ich sterbe ^^)
Ohne Guave
Boolean.TRUE::booleanValue
Predicate
, da es kein Argument braucht.
(foo)->{return true;}
es das Beste ist, was ich tun kann, möchte ich es besser. Aber Sie haben es angesprochenx->true
, was viel besser ist und das erste Problem mildert. Das zweite Problem betrifft die Logik gegenüber der statischen Deklaration. Wenn ich benutzex->true
, ist immer noch Logik involviert, die ich versehentlich vermasseln könnte (zBx->!true
). BeiPredicate.alwaysTrue()
gibt es jedoch keinen Raum für logische Fehler, da es nur eine oder zwei ähnliche Methoden gibt. Außerdem bekomme ich die Vervollständigung des IDE-Codes kostenlos.x->true
ist fast in Ordnung, aber ich habePredicate.alwaysTrue()
aus den oben genannten Gründen immer noch eine Methode geschrieben.