Google Guava ha un predicato che ritorna sempretrue
. Java 8 ha qualcosa di simile per i suoi Predicate
? So che potrei usare (foo)->{return true;}
, ma voglio qualcosa di pre-fatto, analogo a Collections.emptySet()
.
Google Guava ha un predicato che ritorna sempretrue
. Java 8 ha qualcosa di simile per i suoi Predicate
? So che potrei usare (foo)->{return true;}
, ma voglio qualcosa di pre-fatto, analogo a Collections.emptySet()
.
Risposte:
Non ci sono predicati sempre veri e sempre falsi in Java 8. Il modo più conciso per scrivere questi è
x -> true
e
x -> false
Confronta questi con
Predicates.alwaysTrue() // Guava
e infine a una classe interna anonima:
new Predicate<Object>() {
public boolean test(Object x) {
return true;
}
}
Probabilmente il motivo per cui Guava ha questi predicati integrati è che esiste un enorme vantaggio sintattico di una chiamata di metodo statico rispetto a una classe interna anonima. In Java 8, la sintassi lambda è così concisa che esiste uno svantaggio sintattico nello scrivere una chiamata di metodo statica.
Questo è solo un confronto sintattico, però. Vi è probabilmente un piccolo vantaggio in termini di spazio se esistesse un unico predicato sempre vero globale, rispetto alle x -> true
occorrenze distribuite su più classi, ognuna delle quali creerebbe la propria istanza del predicato. È di questo che ti preoccupi? I risparmi non sembravano convincenti, motivo per cui non sono stati aggiunti in primo luogo. Ma potrebbe essere riconsiderato per una versione futura.
AGGIORNAMENTO 2015-04-24
Abbiamo considerato l'aggiunta di una varietà di statica, funzioni con nome, come Predicate.alwaysTrue
, Runnable.noop
e così via, e noi abbiamo deciso di non aggiungere altro nelle future versioni di Java SE.
Certamente c'è un valore in qualcosa che ha un nome rispetto a un lambda scritto, ma questo valore è piuttosto piccolo. Ci aspettiamo che la gente imparare a leggere e scrivere x -> true
e () -> { }
e che il loro utilizzo diventi idiomatica. Anche il valore di Function.identity()
over x -> x
è discutibile.
C'è un piccolo vantaggio in termini di prestazioni nel riutilizzare una funzione esistente invece di valutare un lambda scritto, ma ci aspettiamo che l'uso di questo tipo di funzioni sia così piccolo che un tale vantaggio sarebbe trascurabile, certamente non vale la pena dell'API.
Holger ha anche menzionato nei commenti la possibilità di ottimizzare funzioni composte come Predicate.or
e tali. Anche questo è stato considerato ( JDK-8067971 ), ma è stato considerato un po 'fragile e soggetto a errori, e si verifica abbastanza raramente da non valere lo sforzo di implementarlo.
Vedi anche questa voce FAQ su Lambda .
Predicate.alwaysTrue()
te potresti anche rovinare scrivendo accidentalmente Predicate.alwaysFalse()
.
alwaysTrue()
e alwaysFalse()
. Con l'attuale lambda, ho molte varianti; Sto essenzialmente ricostruendo la formula ogni volta. In sostanza, alwaysTrue()
è un'etichetta semantica per ciò che voglio fare; x->true
lo sta facendo di nuovo ogni volta. Non enorme, ma una considerazione.
Predicate.alwaysTrue()
e Predicate.alwaysFalse()
istanze è, che potevano essere riconosciuti dalla combinazione di metodi come Predicate.or
, Predicate.and
e Predicate.negate()
. Ciò consentirebbe di pre-inizializzare le Predicate
variabili con alwaysTrue()
e aggiungere predicati combinando via and
senza sovraccarico. Poiché le espressioni lambda non hanno alcuna garanzia di identità degli oggetti, ciò potrebbe non riuscire x->true
. A proposito, se ho una classe X
con un static
metodo y(){return true;}
, l'utilizzo X::y
è ancora più breve di x->true
ma non è davvero consigliato ...
x -> true
ha lo svantaggio che devo usare una variabile senza usare. Questo crea inutili carichi cerebrali e anche un avvertimento nel mio IDE. Ho provato a usare _ -> true
, ma questo è un errore di sintassi. A Java manca sicuramente una parola chiave (leggi: keyletter) per "parametro inutilizzato". Spero che qualcosa di simile arriverà in Java 9 (o almeno: Java qualunque cosa io muoia prima ^^)
Senza guava
Boolean.TRUE::booleanValue
Predicate
, in quanto non accetta una discussione.
(foo)->{return true;}
è il meglio che posso fare, voglio di meglio. Ma hai sollevatox->true
, il che è molto meglio e mitiga il primo problema. Il secondo problema riguarda la logica e la dichiarazione statica. Se usox->true
, c'è ancora la logica in questione, che potrei inavvertitamente rovinare (ad esx->!true
.). Ma conPredicate.alwaysTrue()
, non c'è spazio per l'errore logico, poiché esistono solo uno o due metodi simili. Inoltre ottengo il completamento del codice IDE gratuitamente.x->true
va quasi bene, ma ho ancora scritto unPredicate.alwaysTrue()
metodo per i motivi sopra.