如何检查多个对象是否为null?

时间:2015-07-23 08:52:42

标签: java null nullable

通常,我可以看到如下代码构造:

if(a == null || b == null || c == null){
    //...
}

我想知道是否有任何广泛使用的库(谷歌,阿帕奇等)同时检查多个对象的无效性,例如:

if(anyIsNull(a, b, c)){
    //...
}

if(allAreNulls(a, b, c)){
    //...
}

更新

  1. 我完全知道如何自己写
  2. 我知道这可能是程序结构不佳的结果,但这不是一个案例
  3. 让我们更具挑战性,用以下内容替换原始示例:

    if(a != null && a.getFoo() != null && a.getFoo().getBar() != null){
        //...
    }
    
  4. 更新2:

    我已经为Apache Commons Lang库创建了一个pull请求来修复这个差距:

    这些将被纳入commons-lang,版本3.5:

    • anyNotNull (Object... values)
    • allNotNull (Object... values)

7 个答案:

答案 0 :(得分:34)

在Java 8中,您可以使用Stream.allMatch检查所有值是否与特定条件匹配,例如null。不会太短,但可能更容易阅读。

if (Stream.of(a, b, c).allMatch(x -> x == null)) {
    ...
}

并且anyMatchnoneMatch

关于你的“更具挑战性的例子”:在这种情况下,我认为没有办法编写一个懒惰评估的空检查结合,就像你所拥有的那样:

if (a != null && a.getFoo() != null && a.getFoo().getBar() != null) {
    ...
}

使用流,列表或var-arg方法的任何其他方法都会尝试在a.getFoo()被测试之前评估a不是null。您可以将Optionalmap和方法指针一起使用,这些指针将被一个接一个地延迟评估,但这是否使其更具可读性是值得商榷的,并且可能因情况而异(特别是对于更长的类别)名称):

if (Optional.ofNullable(a).map(A::getFoo).map(B::getBar).isPresent()) {
    ...
}

Bar bar = Optional.ofNullable(a).map(A::getFoo).map(B::getBar).orElse(null);

另一个替代方案可能是try访问最里面的项目,但我觉得这不是一个好习惯:

try {
    Bar bar = a.getFoo().getBar();
    ...
catch (NullPointerException e) {
    ...
}

特别是,这也会在访问该元素之后捕获任何其他NPE - 或者你只需​​要在Bar bar = ...和其他所有内容中放置tryif之后的另一个try块中,在可读性或简洁性方面取消任何(可疑的)增益。

(我依旧记得有关像a?.getFoo()?.getBar() != null这样的符号的一些内容,但我不记得它是Java的功能请求还是一些完全不同的语言。)

答案 1 :(得分:22)

EDIT 2018:从Apache Commons lang 3.5开始,有ObjectUtils.allNotNull()ObjectUtils.anyNotNull()

没有

Apache Commons Lang (3.4)Google Guava (18)Spring (4.1.7)都没有提供这样的实用方法。

如果你真的真的需要它,你需要自己写。在现代Java代码中,我可能会考虑需要这样的构造代码味道。

答案 2 :(得分:12)

您还可以使用类似以下方法的内容。它允许您根据需要传递任意数量的参数:

public static boolean isAnyObjectNull(Object... objects) {
    for (Object o: objects) {
        if (o == null) {
            return true;
        }
    }
    return false;
}

您可以使用任意数量的参数调用它:

isAnyObjectNull(a, b, c, d, e, f);

您可以为areAllNull执行类似操作。

public static boolean areAllObjectsNull(Object... objects) {
    for (Object o: objects) {
        if (o != null) {
            return false;
        }
    }
    return true;
}

注意:您也可以使用三元运算符代替if (o == null)。此处显示的两种方法没有错误处理。根据您的需要进行调整。

答案 3 :(得分:1)

借助Objects class

可以实现
public static void requireNonNull(Object... objects) {
    for (Object object : objects) {
        Objects.requireNonNull(object);
    }
}

答案 4 :(得分:0)

您可以创建对象列表并在其中使用yourList.contains(null)

List < Object > obList = new ArrayList < Object > ();

String a = null;
Integer b = 2;
Character c = '9';

obList.add(a);
obList.add(b);
obList.add(c);

System.out.println("List is " + obList);

if (obList.contains(null)) {
    System.out.println("contains null");
} else {
    System.out.println("does not contains null");
}

DEMO

答案 5 :(得分:0)

Apache commons-lang3 自 3.11 版起就有方法 ObjectUtils.allNull(Object... values)

ObjectUtils.allNull(obj1, obj2, obj3);

答案 6 :(得分:0)

我一直在寻找解决方案,但我还没有 apache 作为依赖项,我觉得只为 allNonNull 方法添加它很愚蠢。这是我使用 Predicate#and() / Predicate#or() 的普通 java 解决方案,如下所示:

private static boolean allNonNull(A a) {
    Predicate<A> isNotNull = Objects::nonNull; 
    Predicate<A> hasFoo = someA -> someA.foo != null;
    Predicate<A> hasBar = someA -> someA.foo.bar != null;
    return Optional.ofNullable(a)
        .filter(isNotNull.and(hasFoo.and(hasBar)))
        .isPresent();
}

注意:对于 anyNonNull,只需使用 or() 方法而不是 and()。

调用时,将给出以下输出:

    System.out.println(isValid(new A(new Foo(new Bar())))); // true
    System.out.println(isValid(new A(new Foo(null)))); // false
    System.out.println(isValid(new A(null))); // false
    System.out.println(isValid(null)); // false

使用的类定义:

public static class A {
    public A(Foo foo) {
        this.foo = foo;
    }
    Foo foo;
}

public static class Foo {
    public Foo(Bar bar) {
        this.bar = bar;
    }
    Bar bar;
}

public static class Bar { }