Estou passando pelo código que usa Predicate
em Java. Eu nunca usei Predicate
. Alguém pode me orientar para algum tutorial ou explicação conceitual Predicate
e sua implementação em Java?
Predicate
Estou passando pelo código que usa Predicate
em Java. Eu nunca usei Predicate
. Alguém pode me orientar para algum tutorial ou explicação conceitual Predicate
e sua implementação em Java?
Predicate
Respostas:
Presumo que você esteja falando com.google.common.base.Predicate<T>
da Goiaba.
Da API:
Determina um valor
true
oufalse
para uma determinada entrada. Por exemplo, aRegexPredicate
pode implementarPredicate<String>
e retornar true para qualquer string que corresponda à sua expressão regular fornecida.
Esta é essencialmente uma abstração OOP para um boolean
teste.
Por exemplo, você pode ter um método auxiliar como este:
static boolean isEven(int num) {
return (num % 2) == 0; // simple
}
Agora, dado um List<Integer>
, você pode processar apenas os 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);
}
}
Com Predicate
, o if
teste é abstraído como um tipo. Isso permite que ele interopere com o resto da API, como, por exemplo Iterables
, que tem muitos métodos de utilitário necessários Predicate
.
Assim, agora você pode escrever algo assim:
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);
}
Observe que agora o loop for-each é muito mais simples sem o if
teste. Alcançamos um nível mais alto de abtração definindo Iterable<Integer> evenNumbers
, filter
-ing usando a Predicate
.
Iterables.filter
Predicate
permite Iterables.filter
servir como o que é chamado de função de ordem superior. Por si só, isso oferece muitas vantagens. Veja o List<Integer> numbers
exemplo acima. Suponha que desejamos testar se todos os números são positivos. Podemos escrever algo assim:
static boolean isAllPositive(Iterable<Integer> numbers) {
for (Integer number : numbers) {
if (number < 0) {
return false;
}
}
return true;
}
//...
if (isAllPositive(numbers)) {
System.out.println("Yep!");
}
Com um Predicate
e interoperando com o resto das bibliotecas, podemos escrever isto:
Predicate<Integer> isPositive = new Predicate<Integer>() {
@Override public boolean apply(Integer number) {
return number > 0;
}
};
//...
if (Iterables.all(numbers, isPositive)) {
System.out.println("Yep!");
}
Esperançosamente, agora você pode ver o valor em abstrações mais altas para rotinas como "filtrar todos os elementos pelo predicado fornecido", "verificar se todos os elementos satisfazem o predicado fornecido", etc., para criar um código melhor.
Infelizmente, Java não tem métodos de primeira classe: você não pode passar métodos para Iterables.filter
e Iterables.all
. Você pode, é claro, passar objetos em Java. Portanto, o Predicate
tipo é definido e você passa os objetos que implementam essa interface.
Predicate<Integer>
quando já temos o F<Integer, Boolean>
que faz exatamente a mesma coisa?
Um predicado é uma função que retorna um valor verdadeiro / falso (ou seja, booleano), ao contrário de uma proposição que é um valor verdadeiro / falso (ou seja, booleano). Em Java, não se pode ter funções autônomas e, portanto, cria-se um predicado criando uma interface para um objeto que representa um predicado e, em seguida, fornece-se uma classe que implementa essa interface. Um exemplo de interface para um predicado pode ser:
public interface Predicate<ARGTYPE>
{
public boolean evaluate(ARGTYPE arg);
}
E então você pode ter uma implementação como:
public class Tautology<E> implements Predicate<E>
{
public boolean evaluate(E arg){
return true;
}
}
Para obter uma melhor compreensão conceitual, você pode querer ler sobre lógica de primeira ordem.
Editar
Há uma interface Predicate padrão ( java.util.function.Predicate ) definida na API Java a partir de Java 8. Antes do Java 8, você pode achar conveniente reutilizar a interface com.google.common.base.Predicate de Goiaba .
Além disso, observe que a partir do Java 8, é muito mais simples escrever predicados usando lambdas. Por exemplo, no Java 8 e superior, pode-se passar p -> true
para uma função em vez de definir uma subclasse Tautology nomeada como a acima.
Você pode ver os exemplos de documentos java ou o exemplo de uso de Predicate aqui
Basicamente, é usado para filtrar linhas no conjunto de resultados com base em qualquer critério específico que você possa ter e retornar verdadeiro para as linhas que atendem aos seus critérios:
// the age column to be between 7 and 10
AgeFilter filter = new AgeFilter(7, 10, 3);
// set the filter.
resultset.beforeFirst();
resultset.setFilter(filter);
Somando-se ao que Micheal disse:
Você pode usar Predicate da seguinte maneira na filtragem de coleções em 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;
}
um possível predicado pode 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
? Alguma coisa similar? Algo totalmente diferente?