Google Guava tiene un predicado que siempre regresatrue
. ¿Java 8 tiene algo similar para esto Predicate
? Sé que podría usar (foo)->{return true;}
, pero quiero algo prefabricado, similar a Collections.emptySet()
.
Google Guava tiene un predicado que siempre regresatrue
. ¿Java 8 tiene algo similar para esto Predicate
? Sé que podría usar (foo)->{return true;}
, pero quiero algo prefabricado, similar a Collections.emptySet()
.
Respuestas:
No hay predicados integrados siempre verdaderos y siempre falsos en Java 8. La forma más concisa de escribirlos es
x -> true
y
x -> false
Compare estos con
Predicates.alwaysTrue() // Guava
y finalmente a una clase interna anónima:
new Predicate<Object>() {
public boolean test(Object x) {
return true;
}
}
Probablemente, la razón por la que Guava tiene estos predicados incorporados es que hay una gran ventaja sintáctica de una llamada de método estático sobre una clase interna anónima. En Java 8, la sintaxis lambda es tan concisa que existe una desventaja sintáctica al escribir una llamada a un método estático.
Sin embargo, eso es solo una comparación sintáctica. Probablemente haya una pequeña ventaja de espacio si hubiera un solo predicado global siempre verdadero, en comparación con las x -> true
ocurrencias repartidas en varias clases, cada una de las cuales crearía su propia instancia de predicado. ¿Es esto lo que te preocupa? Los ahorros no parecían convincentes, por lo que probablemente no se agregaron en primer lugar. Pero podría reconsiderarse para un lanzamiento futuro.
ACTUALIZACIÓN 2015-04-24
Hemos considerado la adición de una variedad de estática, funciones con nombre, como Predicate.alwaysTrue
, Runnable.noop
, etc., y hemos decidido no añadir nada más en futuras versiones de Java SE.
Ciertamente, hay algo de valor en algo que tiene un nombre frente a una lambda escrita, pero este valor es bastante pequeño. Esperamos que la gente va a aprender a leer y escribir x -> true
y () -> { }
, y que su uso se convertirá en idiomática. Incluso el valor de Function.identity()
over x -> x
es cuestionable.
Existe una pequeña ventaja de rendimiento al reutilizar una función existente en lugar de evaluar una lambda escrita, pero esperamos que el uso de este tipo de funciones sea tan pequeño que dicha ventaja sería insignificante, ciertamente no vale la pena el aumento de API.
Holger también mencionó en los comentarios la posibilidad de optimizar funciones compuestas tales como Predicate.or
y tales. Esto también se consideró ( JDK-8067971 ), pero se consideró algo frágil y propenso a errores, y ocurría con poca frecuencia como para que no valiera la pena implementarlo.
Consulte también esta entrada de Preguntas frecuentes de Lambda .
Predicate.alwaysTrue()
contigo también podrías equivocarte escribiendo accidentalmente Predicate.alwaysFalse()
.
alwaysTrue()
y alwaysFalse()
. Con la lambda real, tengo muchas variaciones; Básicamente estoy reconstruyendo la fórmula cada vez. En esencia, alwaysTrue()
es una etiqueta semántica para lo que quiero hacer; x->true
en realidad lo está haciendo de nuevo cada vez. No es enorme, pero una consideración.
Predicate.alwaysTrue()
y Predicate.alwaysFalse()
casos es, que podrían ser reconocidos por la combinación de métodos como Predicate.or
, Predicate.and
, y Predicate.negate()
. Esto permitiría preinicializar Predicate
variables con alwaysTrue()
y agregar predicados combinando vía and
sin sobrecarga. Dado que las expresiones lambda no tienen garantía de identidad de objeto, esto podría fallar x->true
. Por cierto, si tengo una clase X
con un static
método y(){return true;}
, el uso X::y
es aún más corto x->true
pero no realmente recomendado ...
x -> true
tiene la desventaja de que tengo que usar una variable sin usar. Esto crea una carga cerebral innecesaria y también una advertencia en mi IDE. Traté de usar _ -> true
, pero eso es un error de sintaxis. A Java definitivamente le falta una palabra clave (léase: keyletter) para "parámetro no utilizado". Espero que algo así llegue en Java 9 (o al menos: Java lo que sea antes de morir ^^)
Sin guayaba
Boolean.TRUE::booleanValue
Predicate
, ya que no requiere una discusión.
(foo)->{return true;}
es lo mejor que puedo hacer, quiero algo mejor. Pero lo mencionastex->true
, lo cual es mucho mejor y mitiga el primer problema. El segundo problema es de lógica frente a declaración estática. Si lo usox->true
, todavía hay lógica involucrada, que podría arruinar inadvertidamente (por ejemplox->!true
). Pero conPredicate.alwaysTrue()
, hay cero espacio para el error lógico, ya que solo hay uno o dos métodos similares. Además, recibo la finalización del código IDE de forma gratuita.x->true
está casi bien, pero aún escribí unPredicate.alwaysTrue()
método por los motivos anteriores.