O Google Guava tem um predicado que sempre retornatrue
. O Java 8 tem algo semelhante para isso Predicate
? Eu sei que poderia usar (foo)->{return true;}
, mas quero algo pré-fabricado, análogo Collections.emptySet()
.
O Google Guava tem um predicado que sempre retornatrue
. O Java 8 tem algo semelhante para isso Predicate
? Eu sei que poderia usar (foo)->{return true;}
, mas quero algo pré-fabricado, análogo Collections.emptySet()
.
Respostas:
Não há predicados sempre verdadeiros e sempre falsos integrados no Java 8. A maneira mais concisa de escrevê-los é
x -> true
e
x -> false
Compare estes com
Predicates.alwaysTrue() // Guava
e finalmente para uma classe interna anônima:
new Predicate<Object>() {
public boolean test(Object x) {
return true;
}
}
Provavelmente, a razão pela qual o Guava possui esses predicados internos é que há uma enorme vantagem sintática de uma chamada de método estático sobre uma classe interna anônima. No Java 8, a sintaxe lambda é tão concisa que há uma desvantagem sintática na gravação de uma chamada de método estática.
Essa é apenas uma comparação sintática, no entanto. Provavelmente, há uma pequena vantagem de espaço se houver um único predicado sempre verdadeiro global, comparado às x -> true
ocorrências espalhadas por várias classes, cada uma das quais criaria sua própria instância de predicado. É com isso que você está preocupado? As economias não pareciam convincentes, e é provavelmente por isso que não foram adicionadas em primeiro lugar. Mas poderia ser reconsiderado para uma versão futura.
ATUALIZAÇÃO 24-04-2015
Nós consideramos a adição de uma variedade de estática, chamados funções, tais como Predicate.alwaysTrue
, Runnable.noop
, etc., e decidimos não adicionar mais em futuras versões do Java SE.
Certamente, existe algum valor em algo que tem um nome versus um lambda gravado, mas esse valor é bem pequeno. Esperamos que as pessoas vão aprender a ler e escrever x -> true
e () -> { }
, e que seu uso se tornará idiomática. Até o valor do Function.identity()
excesso x -> x
é questionável.
Há uma pequena vantagem de desempenho em reutilizar uma função existente, em vez de avaliar um lambda gravado, mas esperamos que o uso desses tipos de funções seja tão pequeno que essa vantagem seja insignificante, certamente não vale o inchaço da API.
Holger também mencionou nos comentários a possibilidade de otimizar funções compostas como Predicate.or
essas. Isso também foi considerado ( JDK-8067971 ), mas foi considerado um tanto frágil e suscetível a erros, ocorrendo com pouca frequência que não valeu a pena o esforço de implementação.
Veja também esta entrada das perguntas frequentes do Lambda .
Predicate.alwaysTrue()
você também pode estragar tudo acidentalmente escrevendo Predicate.alwaysFalse()
.
alwaysTrue()
e alwaysFalse()
. Com o lambda real, tenho muitas variações; Estou essencialmente reconstruindo a fórmula a cada vez. Em essência, alwaysTrue()
é um rótulo semântico para o que eu quero fazer; x->true
está realmente fazendo isso de novo a cada vez. Não é enorme, mas uma consideração.
Predicate.alwaysTrue()
e Predicate.alwaysFalse()
exemplos é que eles poderiam ser reconhecidos através da combinação de métodos como Predicate.or
, Predicate.and
, e Predicate.negate()
. Isso permitiria pré-inicializar Predicate
variáveis com alwaysTrue()
e adicionar predicados combinando via and
sem sobrecarga. Como as expressões lambda não têm garantia de identidade de objeto, isso pode falhar x->true
. By the way, se eu tiver uma classe X
com um static
método y(){return true;}
, usando X::y
é ainda mais curto do que x->true
, mas realmente não recomendado ...
x -> true
tem a desvantagem de que eu tenho que usar uma variável sem uso. Isso cria carga cerebral desnecessária e também um aviso no meu IDE. Eu tentei usar _ -> true
, mas isso é um erro de sintaxe. Definitivamente, falta a Java uma palavra-chave (leia-se: keyletter) para "parâmetro não utilizado". Esperança de que algo como isto virá em Java 9 (ou, pelo menos: Java qualquer que seja antes de morrer ^^)
Sem goiaba
Boolean.TRUE::booleanValue
Predicate
, pois não é necessário um argumento.
(foo)->{return true;}
é o melhor que posso fazer, quero melhor. Mas você mencionoux->true
, o que é muito melhor e atenua a primeira questão. A segunda questão é de lógica vs declaração estática. Se eu usarx->true
, ainda há lógica envolvida, que eu poderia inadvertidamente estragar (por exemplox->!true
). Mas comPredicate.alwaysTrue()
, não há espaço para erro lógico, pois existem apenas um ou dois métodos semelhantes. Além disso, recebo a conclusão do código IDE gratuitamente.x->true
está quase bem, mas ainda escrevi umPredicate.alwaysTrue()
método pelas razões acima.