Wie negieren eine Methode, Referenz-Prädikat
In Java 8, die Sie verwenden können, eine Methode, Verweis auf filter einen Strom, zum Beispiel:
Stream<String> s = ...;
long emptyStrings = s.filter(String::isEmpty).count();
Ist es, eine Möglichkeit zu schaffen, eine Methode, Referenz, ist die negation eines bestehenden, d.h. so etwas wie:
long nonEmptyStrings = s.filter(not(String::isEmpty)).count();
Ich könnte die not
Methode wie unten, aber ich Frage mich, ob das JDK angeboten etwas ähnliches.
static <T> Predicate<T> not(Predicate<T> p) { return o -> !p.test(o); }
JDK-8050818 deckt die neben einer statischen
Scheint, wie Antwort könnte die ultimative Lösung, angepasst JDK/11.
Ich würde wirklich gerne sehen, eine Besondere Methode, die Referenz-syntax für diesen Fall: s.filter(String::!isEmpty)
Predicate.not(Predicate)
Methode. Aber das Problem ist immer noch offen, damit wir sehen diese frühestens in Java 12 (wenn überhaupt).Scheint, wie Antwort könnte die ultimative Lösung, angepasst JDK/11.
Ich würde wirklich gerne sehen, eine Besondere Methode, die Referenz-syntax für diesen Fall: s.filter(String::!isEmpty)
InformationsquelleAutor assylias | 2014-01-31
Du musst angemeldet sein, um einen Kommentar abzugeben.
java-11 bietet eine neue Methode Prädikat#nicht
Also kannst du die Methode Referenz:
vielen Dank für Ihr feedback. Ich bin nicht einverstanden mit dir in einem Sinne, dass dies ist nicht eine Kopie des anderen beantworten. davidillsley empfehlen, benutzerdefinierte statische import-und später veröffentlichte er einen link zu openjdk bug-tracker. Dies ist jedoch ein link zu einer java-11-java-doc. Ich sehe nicht ein, hier eine direkte Kopie von davidillsley Antwort, aber das ist wieder nur meine Meinung.
InformationsquelleAutor Anton Balaniuc
Plane ich, mit dem statischen import die folgenden zu ermöglichen, die für die Methode Referenz benutzt inline:
z.B.
Update:- Gut das JDK/11 möglicherweise mit einem ähnliche Lösung, als gut.
Es ist in guava docs.guava-libraries.googlecode.com/git/javadoc/com/google/...
Aktualisiert Guave link: statisch.javadoc.io/com.google.Guajava/Guave/23.0/com/google/common/...
InformationsquelleAutor davidillsley
Es ist ein Weg, zu Komponieren, eine Methode verweisen, die das Gegenteil einer aktuellen Methode Referenz. Siehe @vlasec die Antwort von unten, die zeigt, wie durch explizites casting der Methode Referenz auf ein
Predicate
und dann konvertieren Sie es mit dernegate
Funktion. Das ist eine Möglichkeit unter ein paar andere nicht allzu lästig Möglichkeiten, es zu tun.Das Gegenteil von diesem:
ist diese:
oder so:
Persönlich bevorzuge ich die Technik später, weil ich es übersichtlicher zu Lesen
it -> !it.isEmpty()
als eine lange ausführliche expliziten cast und dann negieren.Könnte man auch machen, ein Prädikat und wiederverwenden:
Oder, wenn Sie eine collection oder ein array, nur verwenden Sie eine for-Schleife, die einfach ist, hat weniger overhead und *vielleicht **schneller:
*Wenn Sie wissen wollen, was schneller ist, dann verwenden JMH http://openjdk.java.net/projects/code-tools/jmh, und vermeiden Sie hand-benchmark-code, es sei denn, es vermeidet alle JVM-Optimierungen — siehe Java 8: die performance der Streams vs-Sammlungen
**Ich bin immer flak für die Annahme, dass die for-loop-Verfahren schneller ist. Es beseitigt einen stream Schöpfung, beseitigt es mit einer anderen Methode call (negative Funktion für das Prädikat), und es entfällt eine vorübergehende Akku-Liste/Zähler. So ein paar Dinge, die gespeichert werden, durch die Letzte Konstrukt, das könnte damit es schneller geht.
Ich denke, es ist einfacher und schöner, obwohl, wenn auch nicht schneller. Wenn der job erfordert einen hammer und einen Nagel ein, bringen Sie nicht in eine Säge und Leim! Ich weiß, einige von Euch nehmen Ausgabe.
Wunsch-Liste: ich möchte sehen, wie Java
Stream
Funktionen entwickeln jetzt ein bisschen, dass Java-Benutzer sind besser vertraut mit Ihnen. Zum Beispiel, die 'count' - Methode in Stream übernehmen könnte, einePredicate
so, dass dies direkt so:Ich Frage Sie nochmal "viel schneller zu laufen". Die Fragen: (1) Ist es schneller oder 'viel schneller'? (2) Wenn ja, warum? Was haben Sie festgestellt? sind besser zu beantworten, die Sie, der Autor der Anweisung. Ich bin nicht bedenkt, dass es schneller oder langsamer. Danke
Dann werfe ich das aus deiner Frage — Es entfällt ein stream Schöpfung, beseitigt es mit einer anderen Methode call (negative Funktion für das Prädikat), und es entfällt eine vorübergehende Akku-Liste/Zähler. So ein paar Dinge, die gespeichert werden, durch die letzten konstruieren. Ich bin mir nicht sicher, ob es schneller ist oder wie viel schneller, aber ich vermute, es ist 'viel' schneller. Aber vielleicht "viel" ist subjektiv. Es ist einfacher code, der später als negative Prädikate und streams zu tun, eine gerade Anzahl. Meine Präferenz .
Wenn es zur Leistung kommt, nicht davon ausgehen, zu viel!
Negation() scheint wie eine ideale Lösung. Schade, es ist nicht statisch wie
Predicate.negate(String::isEmpty);
ohne das lästige Gießen.InformationsquelleAutor The Coordinator
Predicate
Methodenand
,or
undnegate
.Jedoch
String::isEmpty
ist nicht einPredicate
, es ist nur einString -> Boolean
lambda und könnte es immer noch etwas, z.B.Function<String, Boolean>
. Typ-Inferenz ist, was geschehen muss, ersten. Diefilter
Methode folgert Typ implizit. Aber wenn Sie negieren, es vor der übergabe als argument, es nicht mehr passiert. @Axtavt erwähnt, explizite Inferenz verwendet werden kann, als eine hässliche Art und Weise:Gibt es andere Möglichkeiten hingewiesen, die in anderen Antworten, mit statischen
not
Methode und lambda-wahrscheinlich die besten Ideen. Dies schließt die tl;dr Abschnitt.Jedoch, wenn Sie möchten, einige tiefere Verständnis von lambda-Typ-Inferenz, würde ich mag, um zu erklären, es ein bisschen mehr Tiefe, mit Beispielen. Diese anschauen und versuchen, herauszufinden, was passiert:
Predicate
zuObject
- dumm aber gültigPredicate
zuFunction
es nicht mehr um die Ableitungtest
definiert ist durch seine lambdaInteger
nichtisEmpty
MethodeString::isEmpty
statische Methode mitInteger
argumentIch hoffe, das hilft ein bißchen mehr Einblick in die Art, wie inferrence funktioniert.
InformationsquelleAutor Vlasec
Gebäude auf der anderen die Antworten und persönliche Erfahrungen:
::
Referenz, wie man es sich wünscht(String::isEmpty.negate()
), aber wenn Sie zuweisen, um eine variable erste (oder cast zuPredicate<String>
erste), dass es funktioniert. Ich denke, dass lambda w/!
werden am meisten gelesen in den meisten Fällen, aber es ist hilfreich zu wissen, was können und kann nicht kompilieren.Ich erklärte, dass meine Antwort: Die Methode Referenz ist nicht ein Prädikat, das auf seine eigene. Hier, das casting erfolgt durch die variable.
InformationsquelleAutor Jose Alban
Weitere option ist die Verwendung von lambda-casting in nicht-mehrdeutige Kontexte, in einer Klasse:
... und dann statisch importieren Sie die utility-Klasse:
Es funktioniert für Strings, aber nicht für die Liste: Fehler:(20, 39) java: Referenz als mehrdeutig ist sowohl Methode <T> (java.util.Funktion.Consumer<T>) in der com.Stränge.sbs.Funktion.Lambdas und Methode <T R>als(java.util.Funktion.Funktion<T R>) in der com.Stränge.sbs.Funktion.Lambda-Ausdrücke entsprechen
Daniel, es könnte passieren, wenn Sie versuchen, eine überladene Methode 🙂
Nun, ich verstehe die Typ-Inferenz, viel besser als ursprünglich, ich verstehe, wie es funktioniert. Im Grunde, findet Sie einfach nur die option, die funktioniert. Sieht interessant aus, ich weiß nur nicht, ob es einige bessere Namen, der nicht zu beschränken.
InformationsquelleAutor Askar Kalykov
Sollte nicht
Prädikat#annullieren
sein, was du suchst?Predicate
ersten.Sie haben zu werfen
String::isEmpty()
zuPredicate<String>
vor - es ist sehr hässlich.Verwenden Sie als
Predicate<String> p = (Predicate<String>) String::isEmpty;
undp.negate()
.Ich weiß, aber das Niederlagen der Zweck - ich würde eher schreiben
s -> !s.isEmpty()
in diesem Fall!mmm - ein paar statische Methoden wäre es schöner, wenn...
InformationsquelleAutor Marco13
In diesem Fall u könnte die
org.apache.commons.lang3.StringUtils
und tunNein. Die Frage ist, wie negieren eine beliebige Methode verweisen, und übernimmt
String::isEmpty
als ein Beispiel. Es ist immer noch relevante Informationen, wenn Sie diesen Anwendungsfall, aber wenn es nur Antworten, die die Zeichenkette Fall ist, dann sollte es nicht angenommen werden.InformationsquelleAutor outofBounds
Können Sie Prädikate von Eclipse-Sammlungen
Wenn Sie können nicht ändern die Saiten von
List
:Wenn Sie nur eine negation des
String.isEmpty()
Sie können auchStringPredicates.notEmpty()
.Hinweis: ich bin ein Beitrag zu Eclipse Sammlungen.
InformationsquelleAutor Nikhil Nanivadekar
Ich geschrieben habe, eine komplette utility-Klasse, die (inspiriert durch Suleiman den Vorschlag), der kann Java 8 lambda-Ausdruck, und schalten Sie Sie (falls zutreffend) in einen beliebigen typisierten standard-Java 8-lambda definiert im Paket
java.util.function
. Können Sie zum Beispiel tun:asPredicate(String::isEmpty).negate()
asBiPredicate(String::equals).negate()
Da es zahlreiche Unklarheiten, wenn alle statischen Methoden würde den Namen nur
as()
, entschied ich mich Sie zum aufrufen der Methode "as" gefolgt von dem zurückgegebenen Typ. Dies gibt uns volle Kontrolle über die lambda-interpretation. Unten ist der erste Teil der (etwas große) utility-Klasse enthüllt die Muster verwendet.Haben Sie einen Blick auf die komplette Klasse hier (bei gist).
InformationsquelleAutor Per-Åke Minborg
Wenn man mit Spring Boot (2.0.0+), die Sie verwenden können:
Welche nicht:
return (str != null && !str.isEmpty());
So dass es die geforderte negation Effekt für
isEmpty
InformationsquelleAutor Gilad Peleg
Können Sie dies erreichen, so lange
emptyStrings = s.filter(s->!s.isEmpty()).count();
InformationsquelleAutor Narsi Reddy Nallamilli