Es gibt eine Möglichkeit, einen Methodenverweis zu komponieren, der das Gegenteil eines aktuellen Methodenverweises ist. Siehe die Antwort von @vlasec unten, die zeigt, wie man den Methodenverweis explizit in ein Predicate
umwandelt und ihn dann mit der Funktion negate
konvertiert. Das ist eine Möglichkeit unter ein paar anderen nicht allzu mühsamen Möglichkeiten, es zu tun.
Das Gegenteil davon:
Stream s = ...;
int leereStrings = s.filter(String::isEmpty).count();
ist dies:
Stream s = ...;
int nichtLeereStrings = s.filter(((Predicate) String::isEmpty).negate()).count()
oder dies:
Stream s = ...;
int nichtLeereStrings = s.filter( it -> !it.isEmpty() ).count();
Persönlich ziehe ich die letzte Technik vor, weil ich es klarer finde, it -> !it.isEmpty()
zu lesen als einen langen, ausführlichen expliziten Cast und dann Negation.
Man könnte auch ein Prädikat erstellen und wiederverwenden:
Predicate nichtLeer = (String it) -> !it.isEmpty();
Stream s = ...;
int nichtLeereStrings = s.filter(nichtLeer).count();
Oder, wenn man eine Sammlung oder ein Array hat, einfach eine for-Schleife verwenden, die einfach ist, weniger Overhead hat und möglicherweise schneller ist:
int nichtLeer = 0;
for(String s : list) if(!s.isEmpty()) nichtLeer++;
*Wenn Sie wissen möchten, was schneller ist, verwenden Sie JMH http://openjdk.java.net/projects/code-tools/jmh und vermeiden Sie handgeschriebenen Benchmark-Code, es sei denn, er vermeidet alle JVM-Optimierungen — siehe Java 8: Leistung von Streams vs. Collections
**Ich bekomme Kritik dafür, dass ich die Technik der for-Schleife schneller finde. Sie eliminiert die Erstellung eines Streams, sie eliminiert die Verwendung eines weiteren Methodenaufrufs (negatives Funktion für Prädikat), und sie eliminiert eine temporäre Akkumulatorliste/-zähler. Also ein paar Dinge, die durch das letzte Konstrukt gespart werden, könnten es schneller machen.
Ich finde es jedoch einfacher und schöner, auch wenn es nicht schneller ist. Wenn die Aufgabe einen Hammer und einen Nagel erfordert, bringen Sie keine Kettensäge und Kleber mit! Ich weiß, dass einige von Ihnen damit ein Problem haben.
Wunschliste: Ich würde gerne sehen, dass die Java Stream
-Funktionen sich ein wenig weiterentwickeln, jetzt da Java-Anwender vertrauter mit ihnen sind. Zum Beispiel könnte die Methode 'count' in Stream ein Predicate
akzeptieren, so dass dies direkt gemacht werden kann, wie folgt:
Stream s = ...;
int nichtLeereStrings = s.count(it -> !it.isEmpty());
oder
List list = ...;
int nichtLeereStrings = list.count(it -> !it.isEmpty());