Eingebautes Java 8-Prädikat, das immer wahr zurückgibt?

Lesezeit: 5 Minuten

Benutzer-Avatar
Garret Wilson

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().

Benutzer-Avatar
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.noopusw., 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 erzogen x->true, was viel besser ist und das erste Problem mildert. Das zweite Problem betrifft die Logik vs. die statische Deklaration. Wenn ich benutze x->truees ist immer noch Logik im Spiel, die ich versehentlich vermasseln könnte (z x->!true). Aber mit Predicate.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 a Predicate.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 schreiben Predicate.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() und alwaysFalse(). 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() und Predicate.alwaysFalse() Instanzen ist, dass sie durch die Kombination von Methoden wie erkannt werden könnten Predicate.or, Predicate.andund Predicate.negate(). Dies würde eine Vorinitialisierung ermöglichen Predicate Variablen mit alwaysTrue() und fügen Sie Prädikate hinzu, indem Sie via kombinieren and ohne Aufwand. Da Lambda-Ausdrücke keine Objektidentitätsgarantie haben, kann dies mit fehlschlagen x->true. Übrigens, wenn ich eine Klasse habe X mit einer static Methode y(){return true;}verwenden X::y ist noch kürzer als x->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()

Benutzer-Avatar
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 Predicateda 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 Weil booleanValue() nimmt keine Argumente. Sie könnten es einfach als verwenden Supplier<Boolean> (wie Daniel sagt), was die Frage nicht beantwortet (und wahrscheinlich selten nützlich ist).

    – Didier L

    7. Februar um 19:35 Uhr


1344240cookie-checkEingebautes Java 8-Prädikat, das immer wahr zurückgibt?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy