链式 java.util.function.Predicate 调用以比较谓词

chained java.util.function.Predicate call to compare predicates

我正在尝试让它工作:

Predicate<Integer> predicateInteger = i ->  i>0;
System.out.println(predicateInteger.test(1)); // works and prints true

现在我正在尝试定义另一个谓词,例如 predicateInteger 使用等号:

// stmt below DOES NOT COMPILE : Target type of a lambda conversion must be an interface

Predicate<Integer> predicateEq = predicateInteger.equals(i -> new Boolean(true));
System.out.println(predicateEq.test(8));// I want this to print "TRUE" on equals .

我做错了什么?

这不是一般的谓词和函数式接口(lambda 表达式)。 Predicate class 有唯一的方法 boolean test(T t)。 lambda 表达式与匿名 class 实现没有什么不同。注意没有no equals方法,因此lambda表达式不可比较(就相等性而言)。

Predicate<Integer> predicateInteger = i -> i > 0;
Predicate<Integer> predicateInteger = new Predicate<Integer>() {
    @Override
    public boolean test(Integer i) {
        return i > 0;
    }
}

其实可以直接打印出来的Predicate#testreturnsboolean

Predicate<Integer> integerPredicate = i -> i > 0;
System.out.println(integerPredicate.test(8));                                  // true

您似乎想要 将结果值与用另一个 Predicate.

定义的其他值进行比较
Predicate<Integer> integerPredicate = i -> i > 0;
Predicate<Object> resultPredicate = i -> true;

boolean result = integerPredicate.test(8) == resultPredicate.test("whatever");
System.out.println(result);                                                    // true

请注意,事实上,Predicate<Object> predicate = i -> true 实际上是一个 Supplier,其中 returns 是一个与输入无关的常数值(实际上,它 没有 输入).

Predicate<Integer> integerPredicate = i -> i > 0;
Supplier<Boolean> resultSupplier = () -> true;

boolean result = integerPredicate.test(8) == resultSupplier.get();
System.out.println(result);                                                    // true

但是这样没有意义只要integerPredicate可以直接打印出来,不用resultSupplier.

Predicate<Integer> integerPredicate = i -> i > 0;
System.out.println(integerPredicate.test(8));                                  // true

...我们又回到了起点。


我最后想到的是总是在方法 test 调用时打印出结果。您只需要定义一个装饰器,它包装 Predicate 委托并使用 Consumer<Booleantest 方法调用上提交一个操作,其中 Boolean 是前一个谓词的结果。

@AllArgsConstructor // constructor omitted (Lombok) for sake of brevity
public class CallbackPredicate<T> implements Predicate<T> {

    private final Predicate<T> delegate;
    private final Consumer<Boolean> callback;

    @Override
    public final boolean test(final T t) {
        boolean result = delegate.test(t);
        callback.accept(result);
        return result;
    }
}
Predicate<Integer> integerPredicate = new CallbackPredicate<>(
        i -> i > 0,                                              // Predicate<Integer>
        System.out::println);                                    // Callback

integerPredicate.test(8);                                        // prints true

也可以使用 Predicate#and 方法表示的 AND 子句链接谓词:

Predicate<Integer> largerThanZero = i -> i > 0;
Predicate<Integer> smallerThanSix = i -> i < 6;

Predicate<Integer> betweenZeroAndSix = largerThanZero.and(smallerThanSix);

System.out.println(betweenZeroAndSix.test(-5));                  // false
System.out.println(betweenZeroAndSix.test(5));                   // true
System.out.println(betweenZeroAndSix.test(15));                  // false

这帮助我实现了我想要的:

// when this is the first predicate:
Predicate<Integer> predicateInteger = i ->  i>0;  
// and when this second predicate compares with the first, 
Predicate<Integer> predicateEq = predicateInteger.and(i -> i<6); 
// then :
System.out.println(predicateEq.test(5));// prints true