Google Guava hat ein Prädikat dafür kehrt immer zurück true
. Hat Java 8 etwas Ähnliches für seine Predicate
? Ich weiß, ich könnte es gebrauchen (foo)->{return true;}
aber ich möchte etwas vorgefertigtes, analog zu Collections.emptySet()
.
Eingebautes Java 8-Prädikat, das immer wahr zurückgibt?
Garret Wilson
Stuart Mark
In Java 8 gibt es keine eingebauten immer-wahren und immer-falschen Prädikate. Die prägnanteste 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 hat Guava diese eingebauten Prädikate, weil ein statischer Methodenaufruf einen enormen syntaktischen Vorteil gegenüber einer anonymen inneren Klasse hat. In Java 8 ist die Lambda-Syntax so prägnant, dass es eine Syntax gibt Nachteil zum Schreiben eines statischen Methodenaufrufs.
Das ist aber nur ein syntaktischer Vergleich. Es gibt wahrscheinlich einen kleinen Platzvorteil, wenn es im Vergleich zu ein einziges globales immer-wahres Prädikat gäbe x -> true
Vorkommen verteilen sich über mehrere Klassen, von denen jede ihre eigene Prädikatinstanz erstellen würde. Ist es das, worüber Sie sich Sorgen machen? Die Einsparungen schienen nicht überzeugend, weshalb sie wahrscheinlich gar nicht erst hinzugefügt wurden. Aber es könnte für eine zukünftige Version überdacht werden.
UPDATE 2015-04-24
Wir haben darüber nachgedacht, eine Vielzahl von statischen, benannten Funktionen hinzuzufügen, wie z Predicate.alwaysTrue
, Runnable.noop
usw., und wir haben uns entschieden, in zukünftigen Versionen von Java SE keine weiteren hinzuzufügen.
Sicherlich hat etwas, das einen Namen hat, einen gewissen Wert im Vergleich zu einem ausgeschriebenen Lambda, aber dieser Wert ist ziemlich klein. Wir erwarten, dass die Menschen lesen und schreiben lernen x -> true
und () -> { }
und dass ihre Verwendung idiomatisch wird. Sogar der Wert von Function.identity()
Über x -> x
ist fraglich.
Es gibt einen winzigen Leistungsvorteil, eine vorhandene Funktion wiederzuverwenden, anstatt ein ausgeschriebenes Lambda auszuwerten, aber wir gehen davon aus, dass die Verwendung dieser Art von Funktionen so gering ist, dass ein solcher Vorteil vernachlässigbar wäre, sicherlich nicht das Aufblähen der API wert.
Holger erwähnte in Kommentaren auch die Möglichkeit, zusammengesetzte Funktionen wie z Predicate.or
und derartige. Dies wurde auch berücksichtigt (JDK-8067971), wurde jedoch als etwas anfällig und fehleranfällig eingestuft und trat so selten auf, dass sich der Aufwand für die Implementierung nicht lohnte.
Siehe auch dies Lambda-FAQ Eintrag.
-
Zwei Bedenken: Die erste ist die Kürze. Wenn
(foo)->{return true;}
ist das Beste, was ich tun kann, ich will besser. Aber du hast es erzogenx->true
, was viel besser ist und das erste Problem mildert. Das zweite Problem betrifft die Logik vs. die statische Deklaration. Wenn ich benutzex->true
es ist immer noch Logik im Spiel, die ich versehentlich vermasseln könnte (zx->!true
). Aber mitPredicate.alwaysTrue()
, gibt es keinen Raum für logische Fehler, da es nur ein oder zwei ähnliche Methoden gibt. Außerdem bekomme ich die IDE-Code-Vervollständigung kostenlos.x->true
ist fast in Ordnung, aber ich schrieb noch aPredicate.alwaysTrue()
Methode aus den oben genannten Gründen.– Garret Wilson
24. Oktober 2014 um 23:54 Uhr
-
@GarretWilson Aber mit
Predicate.alwaysTrue()
Sie könnten es auch vermasseln, indem Sie versehentlich schreibenPredicate.alwaysFalse()
.– David Konrad
25. Oktober 2014 um 1:26 Uhr
-
@DavidConrad natürlich. Es gibt immer Möglichkeiten, wie ich Fehler machen kann, und tatsächlich erfinde ich ständig neue. 😉 Ich möchte hier keine Diskussion über etwas Triviales beginnen, aber ich sage nur, dass mein Punkt darin besteht, dass ich mit einer statischen Methodenreferenz ein eingeschränktes Vokabular mit nur zwei Möglichkeiten habe:
alwaysTrue()
undalwaysFalse()
. Mit dem tatsächlichen Lambda habe ich viele Variationen; Ich rekonstruiere im Wesentlichen die Formel jedes Mal. Im Wesentlichen,alwaysTrue()
ist eine semantische Bezeichnung für das, was ich tun möchte;x->true
macht es tatsächlich jedes Mal aufs Neue. Nicht riesig, aber eine Überlegung.– Garret Wilson
25. Oktober 2014 um 1:33 Uhr
-
Ein großer Vorteil von Canonical
Predicate.alwaysTrue()
undPredicate.alwaysFalse()
Instanzen ist, dass sie durch die Kombination von Methoden wie erkannt werden könntenPredicate.or
,Predicate.and
undPredicate.negate()
. Dies würde eine Vorinitialisierung ermöglichenPredicate
Variablen mitalwaysTrue()
und fügen Sie Prädikate hinzu, indem Sie via kombinierenand
ohne Aufwand. Da Lambda-Ausdrücke keine Objektidentitätsgarantie haben, kann dies mit fehlschlagenx->true
. Übrigens, wenn ich eine Klasse habeX
mit einerstatic
Methodey(){return true;}
verwendenX::y
ist noch kürzer alsx->true
aber nicht wirklich zu empfehlen…– Holger
27. Oktober 2014 um 10:45 Uhr
-
Die Redewendung
x -> true
hat den Nachteil, dass ich eine Variable ohne Verwendung verwenden muss. Dies erzeugt unnötige Gehirnlast und auch eine Warnung in meiner IDE. Ich habe versucht zu verwenden_ -> true
, aber das ist ein Syntaxfehler. Java fehlt definitiv ein Schlüsselwort (sprich: Keyletter) für “nicht verwendete Parameter”. Hoffe, dass so etwas in Java 9 kommt (oder zumindest: Java was auch immer, bevor ich sterbe ^^)– Kap
10. November 2015 um 21:27 Uhr
Falls Sie dies im Spring-Framework suchen:
org.springframework.data.util.Predicates
unterstützt dies.
Predicates.isTrue()
, Predicates.isFalse()
boriselec
Ohne Guave
Boolean.TRUE::booleanValue
-
Das ist interessant. Ich bin mir nicht sicher, ob es den Geist der Anfrage vollständig einfängt, aber es gibt Punkte für Kreativität!
– Garret Wilson
21. Oktober 2017 um 1:16 Uhr
-
Aber es ist kein
Predicate
da es kein Argument braucht.– Florent Guillaume
31. Oktober 2017 um 12:12 Uhr
-
Es ist kein Prädikat, es ist eine Methodenreferenz, aber es hat den Vorteil, prägnant zu sein und nicht zu zwingen, einen unbenutzten Parameter zu erwähnen. +1 Übrigens, da es die Verwendung von Guava vermeidet, das ein ernsthaftes Problem der Modularität hat, verdient es meine positive Bewertung;)
– gouessej
20. Februar 2018 um 16:57 Uhr
-
Ihre Methodenreferenz kann Supplier
, aber nicht Predicate zugewiesen werden – DanielK.
25. Mai 2018 um 10:13 Uhr
-
Personen: Bitte hören Sie auf, dies zu bewerten! Diese Antwort ist schlicht falsch. Du kann nicht schreiben
Predicate<Whatever> p = Boolean.TRUE::booleanValue
WeilbooleanValue()
nimmt keine Argumente. Sie könnten es einfach als verwendenSupplier<Boolean>
(wie Daniel sagt), was die Frage nicht beantwortet (und wahrscheinlich selten nützlich ist).– Didier L
7. Februar um 19:35 Uhr