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

Java 如何检查多个对象是否为空?,java,null,nullable,Java,Null,Nullable,通常,我可以看到如下代码结构: if(a == null || b == null || c == null){ //... } 我想知道是否有任何广泛使用的库(Google、Apache等)可以同时检查多个对象的空值,例如: if(anyIsNull(a, b, c)){ //... } 或 更新: 我完全知道怎么自己写 我知道这可能是糟糕的程序结构造成的,但这里不是这样 让我们将其变得更具挑战性,并将原始示例替换为以下内容: if(a != null &&

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

if(a == null || b == null || c == null){
    //...
}
我想知道是否有任何广泛使用的库(Google、Apache等)可以同时检查多个对象的空值,例如:

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

更新:

  • 我完全知道怎么自己写
  • 我知道这可能是糟糕的程序结构造成的,但这里不是这样
  • 让我们将其变得更具挑战性,并将原始示例替换为以下内容:

    if(a != null && a.getFoo() != null && a.getFoo().getBar() != null){
        //...
    }
    
    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();
    }
    
  • 更新2:

    我已经为Apache Commons Lang库创建了一个pull请求,以修复此漏洞:

    • 问题:
    • 公共关系:
    这些将纳入commons lang 3.5版:

    • anyNotNull(对象…值)
    • allNotNull(对象…值)
    在Java8中,您可以使用来检查所有值是否都符合特定条件,例如
    null
    。不短,但可能更容易阅读

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


    关于您的“更具挑战性的示例”:在本例中,我认为没有办法编写空检查的惰性求值连接,就像您的:

    if (a != null && a.getFoo() != null && a.getFoo().getBar() != null) {
        ...
    }
    
    使用streams、List或var arg方法的任何其他方法都会在测试
    a
    是否为
    null
    之前尝试评估
    a.getFoo()
    。您可以将
    Optional
    map
    和方法指针一起使用,这些指针将一个接一个地进行惰性计算,但这是否会使其更具可读性仍有争议,并且可能因情况而异(尤其是对于较长的类名):

    另一种选择可能是
    尝试
    访问最里面的项目,但我觉得这也不是好的做法:

    try {
        Bar bar = a.getFoo().getBar();
        ...
    catch (NullPointerException e) {
        ...
    }
    
    特别是,这还将捕获访问该元素后的任何其他NPE,或者您只需将
    条=…
    放在
    try
    中,并将其他所有内容放在
    if
    块的
    try
    中,从而消除可读性或简洁性方面的任何(有问题的)增益



    有些语言有一种特殊的语言,但似乎Java不是其中之一。这样,您就可以使用类似于
    a?.getFoo()?.getBar()的表示法null
    ,其中
    a?.getFoo()
    将只计算为
    null
    ,如果
    a
    null

    编辑2018:从Apache Commons lang 3.5开始,有和

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

    没有

    没有,并提供了这样一种实用的方法


    如果你真的,真的需要,你需要自己写。在现代java代码中,我可能会考虑这样的结构需要代码嗅觉。

    也可以使用如下方法。它允许您传递任意数量的参数:

    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;
    }
    

    注意:如果(o==null)
    ,也可以使用三元运算符而不是
    。这里显示的两种方法没有错误处理。根据需要调整它。

    您可以创建对象列表,并在其中使用
    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");
    }
    
    ListobList=newarraylist();
    字符串a=null;
    整数b=2;
    字符c='9';
    债务人。添加(a);
    债务人。添加(b);
    债务人。添加(c);
    System.out.println(“列表为”+义务);
    if(义务包含(空)){
    System.out.println(“包含null”);
    }否则{
    System.out.println(“不包含null”);
    }
    
    

    在对象类的帮助下,这是可能的

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

    ApacheCommons-lang3自3.11版起就有了方法

    ObjectUtils.allNull(obj1、obj2、obj3);
    
    我一直在寻找一个解决方案,但我还没有将apache作为一个依赖项,我觉得仅仅为allNonNull方法添加它很愚蠢。下面是我的普通java解决方案,使用/类似于:

    if(a != null && a.getFoo() != null && a.getFoo().getBar() != null){
        //...
    }
    
    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();
    }
    
    使用的类定义:

    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 { }
    

    写起来很容易,但我很少遇到这样的需要。你是否认为你的数据可能结构不好?如果你想要这种直接空校验,你可以简单地通过在列表中传递它并迭代它来创建实用程序。一个变量函数在这里似乎更相关。@DenysSéguret是的,这将是一个更好的问题,我从这类代码中可以看出,你将抛出的异常实际上不能告诉你参数的名称,而它不应该是空的。哦,这实际上是一个好主意。此外,还可以用作谓词。很好,感谢您提供此解决方案。但是,我将用
    Objects::isNull
    替换
    x->x==null
    。在我看来,这是一个更好的版本,可以检查是否有空值
    if(Stream.of(a,b,b).anyMatch(Objects::isNull))
    我发现通过对象内部结构挖掘值的需要有点代码味道。为了避免这种挖掘,请尝试让客户机以更原始的格式提供所需的值。比较:
    public void skine(A){if(A!=null&&A.getFoo()!=null&&A.getFoo().getBar()!=null)}
    vs
    public void clean(Bar){if(Bar!=null)}
    Nice。或者,为了使它比原来的更短,可以使用
    Arrays.asList(a,b,c).contains(null)
    。虽然…对于
    areAllNull
    ,如果
    o!=null
    ?@tobias_k:你完全正确。我删除了我的评论并编辑了代码。你为什么用布尔值而不是原始布尔值?@AlexWien:你可以随意使用(原始值或对象)。根据您的需要更改方法。有时,您必须在应用程序中处理许多布尔对象。通过使用
    Boolean.FALSE
    /
    Boolean.TRUE
    我接收静态对象。这