首页 > 解决方案 > 通用“为空”谓词

问题描述

我写了这个通用谓词:

private static <T> Predicate<T> isNull(){
    return Objects::isNull;
}

但我不能将它与像这样的其他谓词结合使用:

private static Predicate<String> isEmpty(){
    return string -> string.isEmpty();
}

因为这个片段不会编译(期望 Predicate<String> 在 or 操作):

isNull().or(isEmpty())

有什么办法解决吗?谢谢!

标签: javagenericsjava-8predicate

解决方案


由于isNull()是泛型的,并且编译器无法在这样组合时推断出泛型参数,因此您需要显式指定类型参数。

为此,您必须使用类名进行限定,例如Test

Test.<String>isNull().or(isEmpty())

完整示例:

public class Test {
    public static void main(String[] args) {
        Predicate<String> isNullOrEmpty = Test.<String>isNull().or(isEmpty());
        System.out.println(isNullOrEmpty.test(null));   // true
        System.out.println(isNullOrEmpty.test(""));     // true
        System.out.println(isNullOrEmpty.test("Foo"));  // false
    }
    private static <T> Predicate<T> isNull(){
        return Objects::isNull;
    }
    private static Predicate<String> isEmpty(){
        return string -> string.isEmpty();
    }
}

您还可以通过将每个部分分配给一个变量来解决它:

Predicate<String> isNull = isNull(); // String is inferred from assignment operator
Predicate<String> isEmpty = isEmpty();
Predicate<String> isNullOrEmpty = isNull.or(isEmpty);

或者只是第一部分:

Predicate<String> isNull = isNull();
Predicate<String> isNullOrEmpty = isNull.or(isEmpty());

推荐阅读