通用“ is null”谓词

时间:2018-08-22 18:35:15

标签: java generics java-8 predicate

我写了这个通用谓词:

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

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

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

因为此代码段无法编译(期望Predicate 在或操作中):

isNull().or(isEmpty())

有解决的主意吗?谢谢!

4 个答案:

答案 0 :(得分:4)

由于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());

答案 1 :(得分:1)

在我们的项目中,我们对此有一个小的解决方法:

.navbarLink

并将其用于:

.navbarItem {
    flex: 1 1 100%;
}

.navbarLink {
    height: 100%;
    width: 100%;
    display: flex;
    flex-flow: row nowrap;
    align-items: center;
    justify-content: center;
    text-align: center;
}

答案 2 :(得分:0)

调用isNull()时,没有上下文可以推断出T的实际类型。

isNull().or(..)在这里期望Predicate<? super Object>,因此您不能将Predicate<String>传递给它。

翻转它们会起作用(isEmpty().or(isNull())isEmpty()现在返回一个Predicate<String>isEmpty.or(..)期望一个Predicate<? super String>,因此您可以传递一个Predicate<Object>

但这不是不是,因为您想要在检查是否为空之前进行空检查(感谢Slaw @指出这一点。我一直致力于使其能够编译,而我没有注意它的含义/语义。

通过编写,您可以为编译器提供线索T是什么

<YourClassName>.<String>isNull().or(isEmpty());

答案 3 :(得分:0)

专门针对String,您可能只想找一个像这样的单个Predicate-

private static Predicate<String> isNullOrEmpty() {
    return s -> s == null || s.isEmpty();
}

这可以进一步用作

List<String> strings = Arrays.asList("", "one", "two", null, "three");
strings.stream().filter(isNullOrEmpty()).forEach(System.out::println);
// ofcourse the above would print "null" and is less useful

或者借助Java11中的Predicate.not功能,更直观的方法似乎有用-

List<String> strings = Arrays.asList("", "one", "two", null, "three");
strings.stream().filter(Predicate.not(isNullOrEmpty)).forEach(System.out::println); 
// this would print one, two and three