He visto en algunos proyectos que las personas usan Predicate s en lugar de sentencias if puras, como se ilustra con un ejemplo simple a continuación:
int i = 5; // Option 1 if (i == 5) { // Do something System.out.println("if statement"); } // Option 2 Predicate<Integer> predicate = integer -> integer == 5; if (predicate.test(i)) { // Do something System.out.println("predicate"); } ¿Cuál es el punto de preferir Predicate s sobre declaraciones if?
El uso de un predicado hace que su código sea más flexible.
En lugar de escribir una condición que siempre verifique si i == 5 , puede escribir una condición que evalúe un Predicate , lo que le permite pasar diferentes Predicate implementando diferentes condiciones.
Por ejemplo, el Predicate se puede pasar como argumento a un método:
public void someMethod (Predicate<Integer> predicate) { if(predicate.test(i)) { // do something System.out.println("predicate"); } ... } Así es como funciona el método de filter de Stream .
Para el ejemplo exacto que proporcionó, usar un Predicado es una gran exageración. El compilador y luego el tiempo de ejecución crearán:
- un método (predicado sin azúcar)
- una .class que implementará java.util.Predicate
- una instancia de la clase creada en 2
todo esto frente a una declaración if simple.
Y todo esto por un Predicado apátrida . Si su predicado tiene estado, como:
Predicate<Integer> p = (Integer j) -> this.isJGood(j); // you are capturing "this"luego, cada vez que use este Predicado, se creará una nueva instancia (al menos bajo la JVM actual).
En mi opinión, la única opción viable para crear un Predicado de este tipo es, por supuesto, reutilizarlo en varios lugares (como pasar como argumentos a los métodos).
El uso de declaraciones if es la mejor (léase: la más eficaz) forma de comprobar las condiciones binarias.
La declaración de cambio puede ser más rápida para situaciones más complejas.
Un Predicate es una forma especial de Function . De hecho, el arquitecto del lenguaje Java trabaja en una forma de permitir tipos primitivos genéricos. Esto hará que Predicate<T> sea aproximadamente equivalente a Function<T, boolean> (módulo el nombre del método test vs apply).
Si una función (resp. método) toma una o más funciones como argumento(s), la llamamos función de orden superior . Decimos que estamos pasando comportamiento a una función. Esto nos permite crear potentes API.
String result = Match(arg).of( Case(isIn("-h", "--help"), help()), Case(isIn("-v", "--version"), version()), Case($(), cmd -> "unknown command: " + cmd) );Este ejemplo está tomado de Javaslang , una biblioteca para la programación funcional de objetos en Java 8+.
Descargo de responsabilidad: soy el creador de Javaslang.