在Java中谓词

我正在通过在Java中使用Predicate的代码。 我从来没有使用Predicate 。 有人可以指导我对Predicate任何教程或概念性解释及其在Java中的实现吗?

我假设你正在谈论来自Guava的com.google.common.base.Predicate<T>

从API:

确定给定input的true值或false值。 例如,一个RegexPredicate可能实现了Predicate<String> ,并且对任何匹配给定正则expression式的string返回true。

这本质上是一个booleantesting的OOP抽象。

例如,你可能有一个这样的帮手方法:

 static boolean isEven(int num) { return (num % 2) == 0; // simple } 

现在,给定一个List<Integer> ,你可以像这样处理偶数:

  List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10); for (int number : numbers) { if (isEven(number)) { process(number); } } 

通过Predicateiftesting被抽象为一个types。 这使得它可以与API的其他部分互操作,比如Iterables ,它有很多使用Predicate实用方法。

因此,你现在可以写这样的东西:

  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); } 

请注意, if没有iftesting,现在for-each循环要简单得多。 通过使用Predicate进行filter ,我们定义了Iterable<Integer> evenNumbers ,从而达到了更高的抽象级别。

API链接

  • Iterables.filter
    • 返回满足谓词的元素。

在高阶函数上

Predicate允许Iterables.filter作为所谓的高阶函数。 就其本身而言,这提供了许多优点。 以上面的List<Integer> numbers例子。 假设我们要testing所有数字是否都是正数。 我们可以写这样的东西:

 static boolean isAllPositive(Iterable<Integer> numbers) { for (Integer number : numbers) { if (number < 0) { return false; } } return true; } //... if (isAllPositive(numbers)) { System.out.println("Yep!"); } 

通过一个Predicate ,并与其他库进行互操作,我们可以写下这个:

 Predicate<Integer> isPositive = new Predicate<Integer>() { @Override public boolean apply(Integer number) { return number > 0; } }; //... if (Iterables.all(numbers, isPositive)) { System.out.println("Yep!"); } 

希望你现在可以看到更高抽象的例子,比如“用给定谓词过滤所有元素”,“检查所有元素是否满足给定的谓词”等等,以获得更好的代码。

不幸的是,Java没有一stream的方法:你不能将方法传递给Iterables.filterIterables.all 。 当然,您可以在Java中传递对象 。 因此,定义了Predicatetypes,而是传递实现此接口的对象

也可以看看

  • 维基百科/高阶函数
  • 维基百科/filter(高阶函数)

谓词是一个返回true / false(即boolean)值的函数,而不是一个真/假(即布尔值)的命题。 在Java中,不能有独立的函数,因此通过为表示谓词的对象创build一个接口,然后提供一个实现该接口的类来创build一个谓词。 一个谓词接口的例子可能是:

 public interface Predicate<ARGTYPE> { public boolean evaluate(ARGTYPE arg); } 

然后你可能有一个实现,如:

 public class Tautology<E> implements Predicate<E> { public boolean evaluate(E arg){ return true; } } 

为了获得更好的概念理解,您可能需要阅读一阶逻辑。

编辑
Java 8自Java 8 中定义了一个标准的Predicate接口( java.util.function.Predicate )。在Java 8之前,可能会发现重用Guava的com.google.common.base.Predicate接口。

另外,请注意,从Java 8开始,使用lambdas编写谓词要简单得多。 例如,在Java 8及更高版本中,可以将p -> true传递给函数,而不是像上面那样定义一个命名的重言式子类。

您可以在这里查看java doc示例或Predicate的使用示例

基本上它用于根据您可能具有的任何特定条件筛选结果集中的行,并对符合条件的那些行返回true:

  // the age column to be between 7 and 10 AgeFilter filter = new AgeFilter(7, 10, 3); // set the filter. resultset.beforeFirst(); resultset.setFilter(filter); 

加上Micheal所说的话:

在Java中过滤集合时,可以按如下所示使用Predicate:

 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; } 

一个可能的谓词可以是:

 final Predicate<DisplayFieldDto> filterCriteria = new Predicate<DisplayFieldDto>() { public boolean apply(final DisplayFieldDto displayFieldDto) { return displayFieldDto.isDisplay(); } }; 

用法:

  final List<DisplayFieldDto> filteredList= (List<DisplayFieldDto>)filter(displayFieldsList, filterCriteria);