Java 中的谓词
我正在浏览在Java中使用的代码。我从来没有用过.有人可以引导我学习Java中的任何教程或概念解释及其实现吗?Predicate
Predicate
Predicate
我正在浏览在Java中使用的代码。我从来没有用过.有人可以引导我学习Java中的任何教程或概念解释及其实现吗?Predicate
Predicate
Predicate
我假设你说的是来自Guava的com.google.common.base.predicate<T>
。
从 API:
确定给定输入的 或 值。例如,a 可能实现 ,并且对于与其给定正则表达式匹配的任何字符串返回 true。
true
false
RegexPredicate
Predicate<String>
这本质上是测试的OOP抽象。boolean
例如,您可能有一个类似如下的帮助程序方法:
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);
}
}
使用 ,测试被抽象为一个类型。这允许它与API的其余部分进行互操作,例如Iterables
,它们具有许多实用程序方法,这些方法采用.Predicate
if
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
filter
Predicate
Iterables.filter
Predicate
允许用作所谓的高阶函数。就其本身而言,这提供了许多优势。以上面的例子为例。假设我们要测试是否所有数字都是正数。我们可以这样写: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!");
}
使用 ,并与其余库互操作,我们可以改为编写以下内容: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没有一流的方法:你不能将方法传递给 和 。当然,您可以在Java中传递对象。因此,定义了类型,并改为传递实现此接口的对象。Iterables.filter
Iterables.all
Predicate
谓词是返回真/假(即布尔值)值的函数,而不是作为真/假(即布尔值)值的命题。在Java中,不能有独立的函数,因此可以通过为表示谓词的对象创建一个接口来创建谓词,然后提供实现该接口的类。谓词的接口示例可能是:
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 API中定义了一个标准的谓词接口(java.util.function.Predicate)。在Java 8之前,你可能会发现重用Guava的com.google.common.base.Predicate接口很方便。
另外,请注意,从 Java 8 开始,使用 lambdas 编写谓词要简单得多。例如,在Java 8及更高版本中,可以传递给一个函数,而不是像上面那样定义一个命名的Tautology子类。p -> true