如何检查多个对象的空性?

2022-08-31 13:28:42

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

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

我想知道是否有任何广泛使用的库(Google,Apache等)可以同时检查多个对象的空性,例如:

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

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

更新:

  1. 我完全知道如何自己写
  2. 我知道这可能是程序结构不佳的结果,但这里不是这种情况
  3. 让我们让它更具挑战性,并用这样的东西替换原始示例:

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

更新 2:

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

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

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

答案 1

在 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()anullOptionalmap

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 - 要么是那个,要么你必须只将 in 和其他所有内容放在另一个块中,然后取消任何(可疑的)可读性或简洁性收益。Bar bar = ...tryiftry


有些语言有一个安全导航运算符,但Java似乎不是其中之一。这样,您可以使用类似 的表示法,其中将只计算为 if is 。但是,您可以使用自定义函数和 ,返回或仅返回值,或者如果您愿意,可以模拟此类行为:a?.getFoo()?.getBar() != nulla?.getFoo()nullanulllambdaOptionalnull

public static <T> Optional<T> tryGet(Supplier<T> f) {
    try {
        return Optional.of(f.get());
    } catch (NullPointerException e) {
        return Optional.empty();
    }
}

Optional<Bar> bar = tryGet(() -> a.getFoo().getBar(););

答案 2

编辑2018:从Apache Commons lang 3.5开始,已经有了ObjectUtils.allNotNull()ObjectUtils.anyNotNull()


不。

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

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