通用“为空”谓词

ita*_*ind 5 java generics predicate java-8

我写了这个通用谓词:

private static <T> Predicate<T> isNull(){
    return Objects::isNull;
}
Run Code Online (Sandbox Code Playgroud)

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

private static Predicate<String> isEmpty(){
    return string -> string.isEmpty();
}
Run Code Online (Sandbox Code Playgroud)

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

isNull().or(isEmpty())
Run Code Online (Sandbox Code Playgroud)

有什么想法可以解决吗?谢谢!

And*_*eas 6

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

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

Test.<String>isNull().or(isEmpty())
Run Code Online (Sandbox Code Playgroud)

完整示例:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Predicate<String> isNull = isNull(); // String is inferred from assignment operator
Predicate<String> isEmpty = isEmpty();
Predicate<String> isNullOrEmpty = isNull.or(isEmpty);
Run Code Online (Sandbox Code Playgroud)

或者只是第一部分:

Predicate<String> isNull = isNull();
Predicate<String> isNullOrEmpty = isNull.or(isEmpty());
Run Code Online (Sandbox Code Playgroud)