Java 具有公共输入参数的谓词<T>

Java Predicate<T> with common input parameters

我在 Java 中借助 Predicate 编写了以下 3 个方法:

public static final Predicate<CustomerType> function1 = ct ->
        "OWNER".equals(ct.getFactType()) && "FULL".equals(ct.getFactValue());


public static final Predicate<CustomerType> function2 = ct ->
        "OWNER".equals(ct.getFactType()) && ("NONFULL".equals(ct.getFactValue()) || "FULL".equals(ct.getFactValue()));


public static final Predicate<CustomerType> function3 = ct ->
        ("INDIRECT".equals(ct.getFactType()) || "NONINDIRECT".equals(ct.getFactType()))
                && "YES".equals(ct.getFactValue());

如您所见,这三个函数有很多共同的元素(例如CustomerValue.getFactValue和CustomerValue.getFactType)。

有没有办法在每三个函数中将这些输入作为输入参数? 如果是,如何?

我有以下方法可以根据谓词给我一个布尔结果:

private boolean checkJohn(List<CustomerType> custTypes) {
    return custTypes.stream().anyMatch(Functional.method2);
}

private boolean checkJoan(List<CustomerType> custTypes) {
    return custTypes.stream().anyMatch(Functional.method1);
}

由于输入参数的个数不同,因为两个参数都可以有A值或B值,我有点卡了...


编辑:

如果我有以下情况:

public static final BiPredicate<String, CustomerType> functionName = (ct, ft) ->
        ("NATPERSON".equals(ct) && ("INDIRECT".equals(ft.getFactType()) && "YES".equals(ft.getFactValue())))
                || ("NONNATPERS".equals(ct) && ("NONINDIRECT".equals(ft.getFactType()) && "YES".equals(ft.getFactValue())));

...这很好用...

但是如果我创建:

Predicate<PersonType> IS_NATPERSON = wrap("NATPERSON"::equals); 
Predicate<PersonType> IS_NONNATPERSON = wrap("NONNATPERSON"::equals);

使用以下包装:

private static Predicate<PersonType> wrap(Predicate<String> predicate) {
    return ft -> predicate.test(ft.getType().getCustomerType());
}

并尝试调用:

public static final BiPredicate<PersonType, CustomerType> functionName2 = (IS_NATPERSON.and((IS_INDIRECT).and(IS_YES))).or(IS_NONNATPERSON.and((IS_NONINDIRECT).and(IS_YES)));

然后我明白了:

and (java.util.function.Predicate<? super PersonType>) in Predicate cannot be applied to (java.util.function.Predicate<CustomerType>)

有什么想法吗?

您可以使用 BiPredicate 类型,它接受两个参数。然后调用者的工作就是调用 .getFactType().getFactValue().

您还可以通过为每个部分创建常量然后使用 .and.or 方法组合它们来简化阅读:

static final BiPredicate<String, String> IS_OWNER = (t, v) -> "OWNER".equals(t);
// Etc

static final BiPredicate<String, String> f1 = IS_OWNER.and(IS_FULL);

// Using a BiPredicate by unwrapping a customer type:
if (f1.test(ct.getFactType(), ct.getFactValue())) {

理想情况下,事实类型和事实值的类型应该不同,以免意外混淆。

如果您不想将解包责任推给调用者,您可以编写一个静态助手,将 BiPredicate<String, String> 变成 Predicate<CustomerType>:

static Predicate<CustomerType> wrap(BiPredicate<String, String> bp) {
    return ct -> bp.test(ct.getFactType(), ct.getFactValue());
}

static final Predicate<CustomerType> IS_OWNER = wrap((t, v) -> "OWNER".equals(t));
// Etc

static final Predicate<CustomerType> f1 = IS_OWNER.and(IS_FULL);