Estoy revisando el código que se usa Predicate
en Java. Nunca lo he usado Predicate
. ¿Alguien puede guiarme a algún tutorial o explicación conceptual Predicate
y su implementación en Java?
Predicate
Estoy revisando el código que se usa Predicate
en Java. Nunca lo he usado Predicate
. ¿Alguien puede guiarme a algún tutorial o explicación conceptual Predicate
y su implementación en Java?
Predicate
Respuestas:
Supongo que estás hablando com.google.common.base.Predicate<T>
de Guava.
Desde la API:
Determina un valor
true
ofalse
para una entrada determinada. Por ejemplo, aRegexPredicate
podría implementarPredicate<String>
y devolver verdadero para cualquier cadena que coincida con su expresión regular dada.
Esto es esencialmente una abstracción OOP para una boolean
prueba.
Por ejemplo, puede tener un método auxiliar como este:
static boolean isEven(int num) {
return (num % 2) == 0; // simple
}
Ahora, dado un List<Integer>
, puede procesar solo los números pares como este:
List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
for (int number : numbers) {
if (isEven(number)) {
process(number);
}
}
Con Predicate
, la if
prueba se abstrae como un tipo. Esto le permite interoperar con el resto de la API, por ejemplo Iterables
, que tiene muchos métodos de utilidad que toma Predicate
.
Por lo tanto, ahora puede escribir algo como esto:
Predicate<Integer> isEven = new Predicate<Integer>() {
@Override public boolean apply(Integer number) {
return (number % 2) == 0;
}
};
Iterable<Integer> evenNumbers = Iterables.filter(numbers, isEven);
for (int number : evenNumbers) {
process(number);
}
Tenga en cuenta que ahora el ciclo for-each es mucho más simple sin la if
prueba. Hemos alcanzado un nivel más alto de abtracción al definir Iterable<Integer> evenNumbers
, al filter
utilizar un Predicate
.
Iterables.filter
Predicate
permite Iterables.filter
servir como lo que se llama una función de orden superior. Por sí solo, esto ofrece muchas ventajas. Tome el List<Integer> numbers
ejemplo anterior. Supongamos que queremos probar si todos los números son positivos. Podemos escribir algo como esto:
static boolean isAllPositive(Iterable<Integer> numbers) {
for (Integer number : numbers) {
if (number < 0) {
return false;
}
}
return true;
}
//...
if (isAllPositive(numbers)) {
System.out.println("Yep!");
}
Con a Predicate
, e interoperando con el resto de las bibliotecas, podemos escribir esto:
Predicate<Integer> isPositive = new Predicate<Integer>() {
@Override public boolean apply(Integer number) {
return number > 0;
}
};
//...
if (Iterables.all(numbers, isPositive)) {
System.out.println("Yep!");
}
Es de esperar que ahora pueda ver el valor en abstracciones más altas para rutinas como "filtrar todos los elementos por el predicado dado", "comprobar si todos los elementos satisfacen el predicado dado", etc. para mejorar el código.
Desafortunadamente, Java no tiene métodos de primera clase: no puede pasar métodos a Iterables.filter
y Iterables.all
. Por supuesto, puede pasar objetos en Java. Por lo tanto, el Predicate
tipo está definido y, en su lugar, pasa objetos que implementan esta interfaz.
Predicate<Integer>
cuando ya tenemos F<Integer, Boolean>
cuál hace exactamente lo mismo?
Un predicado es una función que devuelve un valor verdadero / falso (es decir, booleano), a diferencia de una proposición que es un valor verdadero / falso (es decir, booleano). En Java, no se pueden tener funciones independientes, por lo que se crea un predicado creando una interfaz para un objeto que representa un predicado y luego se proporciona una clase que implementa esa interfaz. Un ejemplo de una interfaz para un predicado podría ser:
public interface Predicate<ARGTYPE>
{
public boolean evaluate(ARGTYPE arg);
}
Y luego podría tener una implementación como:
public class Tautology<E> implements Predicate<E>
{
public boolean evaluate(E arg){
return true;
}
}
Para obtener una mejor comprensión conceptual, es posible que desee leer sobre lógica de primer orden.
Editar
Existe una interfaz Predicate estándar ( java.util.function.Predicate ) definida en la API de Java a partir de Java 8. Antes de Java 8, puede que le resulte conveniente reutilizar la interfaz com.google.common.base.Predicate de Guayaba .
Además, tenga en cuenta que a partir de Java 8, es mucho más sencillo escribir predicados utilizando lambdas. Por ejemplo, en Java 8 y superior, se puede pasar p -> true
a una función en lugar de definir una subclase de Tautología con nombre como la anterior.
Puede ver los ejemplos de java doc o el ejemplo de uso de Predicate aquí
Básicamente, se utiliza para filtrar filas en el conjunto de resultados en función de cualquier criterio específico que pueda tener y devolver verdadero para aquellas filas que cumplen con sus criterios:
// the age column to be between 7 and 10
AgeFilter filter = new AgeFilter(7, 10, 3);
// set the filter.
resultset.beforeFirst();
resultset.setFilter(filter);
Añadiendo a lo que ha dicho Micheal :
Puede usar Predicate de la siguiente manera en el filtrado de colecciones en java:
public static <T> Collection<T> filter(final Collection<T> target,
final Predicate<T> predicate) {
final Collection<T> result = new ArrayList<T>();
for (final T element : target) {
if (predicate.apply(element)) {
result.add(element);
}
}
return result;
}
un posible predicado puede ser:
final Predicate<DisplayFieldDto> filterCriteria =
new Predicate<DisplayFieldDto>() {
public boolean apply(final DisplayFieldDto displayFieldDto) {
return displayFieldDto.isDisplay();
}
};
Uso:
final List<DisplayFieldDto> filteredList=
(List<DisplayFieldDto>)filter(displayFieldsList, filterCriteria);
Predicate
? ¿Algo parecido? ¿Algo completamente diferente?