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

问题描述

我正在努力让它发挥作用:

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

现在我正在尝试使用 equals 定义另一个谓词,例如 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 类具有唯一的方法 boolean test(T t)。 lambda 表达式与匿名类实现没有什么不同。请注意,没有没有 equals 方法,因此 lambda 表达式不可比较(就相等而言)。

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

其实Predicate#test返回的是boolean,可以直接打印出来:

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,无论输入如何,它都会返回一个常量值(实际上,它没有 输入)。

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 委托并使用 test 提交对 Consumer<Boolean 方法调用的操作,其中 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

也可以使用 AND 方法表示的 Predicate#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