我假设你正在谈论com.google.common.base.Predicate<T>来自番石榴。
从API:
确定一个true
or false
给定输入的值。例如,一个RegexPredicate
可能会实施Predicate<String>
,并为任何与其给定正则表达式匹配的字符串返回 true。
这本质上是一个 OOP 抽象boolean
test.
例如,您可能有这样的辅助方法:
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);
}
}
With Predicate
, the if
测试被抽象为一种类型。这允许它与 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);
}
请注意,现在 for-each 循环更加简单,没有if
测试。我们通过定义达到了更高的抽象级别Iterable<Integer> evenNumbers
, by filter
-使用aPredicate
.
API链接
关于高阶函数
Predicate
allows Iterables.filter
充当所谓的高阶函数。就其本身而言,这提供了许多优点。采取List<Integer> numbers
上面的例子。假设我们想测试所有数字是否都是正数。我们可以这样写:
static boolean isAllPositive(Iterable<Integer> numbers) {
for (Integer number : numbers) {
if (number < 0) {
return false;
}
}
return true;
}
//...
if (isAllPositive(numbers)) {
System.out.println("Yep!");
}
With a 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 没有一流的方法:你不能通过methods大约到Iterables.filter
and Iterables.all
。当然你也可以绕过去objects在爪哇。就这样Predicate
类型已定义,并且您通过objects而是实现这个接口。
See also