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()
.
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 .
(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.Predicate.alwaysTrue()
tobą możesz też schrzanić, przypadkowo piszącPredicate.alwaysFalse()
.alwaysTrue()
ialwaysFalse()
. Przy rzeczywistej lambdzie mam wiele odmian; Zasadniczo rekonstruuję formułę za każdym razem. W istociealwaysTrue()
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 jakPredicate.or
,Predicate.and
iPredicate.negate()
. Pozwoliłoby to na wstępne zainicjowaniePredicate
zmiennych zalwaysTrue()
i dodanie predykatów poprzez połączenie przelotekand
bez narzutu. Ponieważ wyrażenia lambda nie mają gwarancji tożsamości obiektu, może to się nie powieść w przypadkux->true
. Nawiasem mówiąc, jeśli mam klasęX
zstatic
metodąy(){return true;}
, użycieX::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
źródło
Predicate
, ponieważ nie wymaga kłótni.