有没有办法在for-each循环迭代开始之前避免空值检查?

时间:2011-05-20 21:50:32

标签: java for-loop foreach

每次我必须迭代一个集合时,我最终都会检查null,就在for-each循环的迭代开始之前。像这样:

if( list1 != null ){
    for(Object obj : list1){

    }
}

是否有更短的方式,以便我们可以避免编写“if”块? 注意:我使用的是Java 5,并且会在一段时间内坚持使用它。

10 个答案:

答案 0 :(得分:77)

如果可能,您应该设计代码,使首先不是null的集合。

null收藏品是不好的做法(因此);你应该使用空集合。 (例如,Collections.emptyList()

或者,您可以创建一个实现Iterable的包装类并获取集合,并处理null集合。
然后你可以写foreach(T obj : new Nullable<T>(list1))

答案 1 :(得分:39)

public <T extends Iterable> T nullGuard(T item) {
  if (item == null) {
    return Collections.EmptyList;
  } else {
    return item;
  }
}

允许你写

for (Object obj : nullGuard(list)) {
  ...
}

当然,这实际上只是将复杂性转移到其他地方。

答案 2 :(得分:32)

我想正确的答案是:没有办法让它缩短。有一些技巧,如评论中的那些,但我不认为自己使用它们。我认为写一个“if”块比使用这些技术更好。并且是..在任何人再次提到之前:)“理想情况下”代码应该被设计为使得列表永远不应该是 null

答案 3 :(得分:16)

已经是2017年,您现在可以使用Apache Commons Collections4

用法:

for(Object obj : CollectionUtils.emptyIfNull(list1)){
    // Do your stuff
}

答案 4 :(得分:15)

在Java 8中,使用java.util.OptionalifPresent方法可以获得另一种解决方案。

Optional.ofNullable(list1).ifPresent(l -> l.forEach(item -> {/* do stuff */}));

所以,不是针对确切问题的解决方案,而是一个oneliner,可能更优雅。

答案 5 :(得分:11)

Null check in an enhanced for loop

public static <T> Iterable<T> emptyIfNull(Iterable<T> iterable) {
    return iterable == null ? Collections.<T>emptyList() : iterable;
}

然后使用:

for (Object object : emptyIfNull(someList)) { ... }

答案 6 :(得分:9)

Apache Commons

for (String code: ListUtils.emptyIfNull(codes)) {

}           

Google Guava

for (String code: Optional.of(codes).get()) {

}

答案 7 :(得分:7)

您希望它缩短多少?它只是一个额外的2行,它清晰简洁的逻辑。

我认为您需要决定的更重要的事情是null是否为有效值。如果它们无效,您应该编写代码以防止它发生。那你就不需要这种检查了。如果您在执行foreach循环时遇到异常,则表示代码中的其他位置存在错误。

答案 8 :(得分:5)

1)如果list1是一个类的成员,则在构造函数中创建列表,使其存在,并且非空,但为空。

2)for(Object obj:list1!= null?list1:new ArrayList())

答案 9 :(得分:1)

另一种Java 8+方法是创建一个使用null值时不会崩溃的forEach方法:

public static <T> void forEach(Iterable<T> set, Consumer<T> action) {
    if (set != null) {
        set.forEach(action);
    }
}

自己定义的foreach的用法与本机Java 8接近:

ArrayList<T> list = null;

//java 8+ (will throw a NullPointerException)
list.forEach(item -> doSomething(...) );

//own implementation
forEach(list, item -> doSomething(...) );