Google Guava ma predykat, który zawsze zwracatrue
. Czy Java 8 ma coś podobnego Predicate
? Wiem, że mógłbym użyć (foo)->{return true;}
, ale chcę coś gotowego, analogicznego do Collections.emptySet()
.
Google Guava ma predykat, który zawsze zwracatrue
. Czy Java 8 ma coś podobnego Predicate
? Wiem, że mógłbym użyć (foo)->{return true;}
, ale chcę coś gotowego, analogicznego do Collections.emptySet()
.
Odpowiedzi:
W Javie 8 nie ma wbudowanych predykatów zawsze prawdziwych i zawsze fałszywych. Najbardziej zwięzłym sposobem ich zapisania jest
x -> true
i
x -> false
Porównaj je z
Predicates.alwaysTrue() // Guava
i wreszcie do anonimowej klasy wewnętrznej:
new Predicate<Object>() {
public boolean test(Object x) {
return true;
}
}
Prawdopodobnie powodem, dla którego Guava ma te wbudowane predykaty, jest ogromna przewaga składniowa wywołania metody statycznej nad anonimową klasą wewnętrzną. W Javie 8 składnia lambda jest tak zwięzła, że zapisywanie wywołania metody statycznej ma wadę składniową .
To tylko porównanie składniowe. Prawdopodobnie istnieje niewielka przewaga miejsca, gdyby istniał jeden globalny predykat zawsze prawdziwy, w porównaniu z x -> true
wystąpieniami rozproszonymi w wielu klasach, z których każda utworzyłaby własną instancję predykatu. Czy o to się martwisz? Oszczędności nie wydawały się przekonujące i prawdopodobnie dlatego nie zostały dodane w pierwszej kolejności. Ale można by to ponownie rozważyć pod kątem przyszłej wersji.
UPDATE 2015-04-24
Musimy rozważyć dodanie różnych statycznych, nazwanych funkcji, takich jak Predicate.alwaysTrue
, Runnable.noop
itp, a my nie zdecydowała się dodać więcej w przyszłości wersji Java SE.
Z pewnością jest jakaś wartość w czymś, co ma nazwę, w porównaniu z wypisaną lambdą, ale ta wartość jest dość mała. Oczekujemy, że ludzie nauczą się czytać i pisać, x -> true
a () -> { }
ich używanie stanie się idiomatyczne. Nawet wartość Function.identity()
over x -> x
jest wątpliwa.
Ponowne wykorzystanie istniejącej funkcji zamiast szacowania wypisanej lambdy ma niewielką zaletę w zakresie wydajności, ale spodziewamy się, że użycie tego rodzaju funkcji będzie tak małe, że taka przewaga byłaby znikoma, a na pewno nie warta rozbudowy interfejsu API.
Holger wspomniał także w komentarzach o możliwości optymalizacji złożonych funkcji, takich jak Predicate.or
i takie. Zostało to również wzięte pod uwagę ( JDK-8067971 ), ale zostało uznane za nieco delikatne i podatne na błędy oraz występowało na tyle rzadko, że nie było warte wysiłku, aby go wdrożyć.
Zobacz także ten wpis Lambda FAQ .
Predicate.alwaysTrue()
tobą możesz też schrzanić, przypadkowo pisząc Predicate.alwaysFalse()
.
alwaysTrue()
i alwaysFalse()
. Przy rzeczywistej lambdzie mam wiele odmian; Zasadniczo rekonstruuję formułę za każdym razem. W istocie alwaysTrue()
jest semantyczną etykietą tego, co chcę zrobić; x->true
za każdym razem robi to od nowa. Niezbyt duże, ale warto się zastanowić.
Predicate.alwaysTrue()
iPredicate.alwaysFalse()
wypadkach jest to, że mogą one być uznane przez łączenie metod jak Predicate.or
, Predicate.and
i Predicate.negate()
. Pozwoliłoby to na wstępne zainicjowanie Predicate
zmiennych z alwaysTrue()
i dodanie predykatów poprzez połączenie przelotek and
bez narzutu. Ponieważ wyrażenia lambda nie mają gwarancji tożsamości obiektu, może to się nie powieść w przypadku x->true
. Nawiasem mówiąc, jeśli mam klasę X
z static
metodą y(){return true;}
, użycie X::y
jest nawet krótsze niż, x->true
ale niezbyt zalecane…
x -> true
ma tę wadę, że muszę używać zmiennej bez użycia. Stwarza to niepotrzebne obciążenie mózgu, a także ostrzeżenie w moim IDE. Próbowałem użyć _ -> true
, ale jest to błąd składniowy. W Javie zdecydowanie brakuje słowa kluczowego (czytaj: literka klucza) dla „nieużywanego parametru”. Mam nadzieję, że coś takiego pojawi się w Javie 9 (lub przynajmniej: Java, cokolwiek zanim umrę ^^)
Bez guawy
Boolean.TRUE::booleanValue
Predicate
, ponieważ nie wymaga kłótni.
(foo)->{return true;}
to najlepsze, co mogę zrobić, chcę lepiej. Ale poruszyłeśx->true
, co jest znacznie lepsze i łagodzi pierwszą kwestię. Druga kwestia to logika kontra deklaracja statyczna. Jeśli używamx->true
, nadal jest zaangażowana logika, którą mógłbym niechcący zepsuć (npx->!true
.). Ale w przypadkuPredicate.alwaysTrue()
nie ma miejsca na błędy logiczne, ponieważ istnieje tylko jedna lub dwie podobne metody. Dodatkowo otrzymuję bezpłatne uzupełnianie kodu IDE.x->true
jest prawie w porządku, ale nadal napisałemPredicate.alwaysTrue()
metodę z powyższych powodów.