Istnieje sposób na skomponowanie odwołania do metody, które jest przeciwieństwem bieżącego odwołania do metody. Zobacz odpowiedź @ vlasec poniżej, która pokazuje, jak jawnie rzutować odwołanie do metody na a, Predicatea następnie przekonwertować ją za pomocą negatefunkcji. To jeden ze sposobów na kilka innych niezbyt kłopotliwych sposobów.
Przeciwieństwo tego:
Stream<String> s = ...;
int emptyStrings = s.filter(String::isEmpty).count();
czy to jest:
Stream<String> s = ...;
int notEmptyStrings = s.filter(((Predicate<String>) String::isEmpty).negate()).count()
albo to:
Stream<String> s = ...;
int notEmptyStrings = s.filter( it -> !it.isEmpty() ).count();
Osobiście wolę późniejszą technikę, ponieważ uważam, że czytanie it -> !it.isEmpty()jest łatwiejsze niż długa pełna wypowiedź, a następnie negacja.
Można również zrobić predykat i użyć go ponownie:
Predicate<String> notEmpty = (String it) -> !it.isEmpty();
Stream<String> s = ...;
int notEmptyStrings = s.filter(notEmpty).count();
Lub, jeśli masz kolekcję lub tablicę, po prostu użyj pętli for, która jest prosta, ma mniejszy narzut i * może być ** szybsza:
int notEmpty = 0;
for(String s : list) if(!s.isEmpty()) notEmpty++;
* Jeśli chcesz wiedzieć, co jest szybsze, użyj JMH http://openjdk.java.net/projects/code-tools/jmh i unikaj ręcznego kodu testowego, chyba że unika się wszystkich optymalizacji JVM - patrz Java 8: wydajność strumieni vs Kolekcje
** Dostaję błąd, sugerując, że technika for-loop jest szybsza. Eliminuje tworzenie strumienia, eliminuje użycie innego wywołania metody (funkcja ujemna dla predykatu) i eliminuje tymczasową listę / licznik akumulatorów. Kilka rzeczy, które są zapisywane przez ostatni konstrukt, które mogą go przyspieszyć.
Myślę, że jest to jednak prostsze i przyjemniejsze, nawet jeśli nie szybsze. Jeśli praca wymaga młota i gwoździa, nie przynoś piły łańcuchowej i kleju! Wiem, że niektórzy z was mają z tym problem.
lista życzeń: Chciałbym, aby Streamfunkcje Java ewoluowały nieco teraz, gdy użytkownicy Java są z nimi bardziej zaznajomieni. Na przykład metoda „count” w Streamie może zaakceptować a, Predicatedzięki czemu można to zrobić bezpośrednio w następujący sposób:
Stream<String> s = ...;
int notEmptyStrings = s.count(it -> !it.isEmpty());
or
List<String> list = ...;
int notEmptyStrings = lists.count(it -> !it.isEmpty());
Predicate.not(Predicate)metody statycznej . Ale ten problem jest nadal otwarty, więc zobaczymy to najwcześniej w Javie 12 (jeśli w ogóle).