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, Predicate
a następnie przekonwertować ją za pomocą negate
funkcji. 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 Stream
funkcje 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, Predicate
dzię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).