增强的for循环中的Null检查

在Java中防止for循环为空的最好方法是什么?

这看起来很丑陋:

if (someList != null) {
for (Object object : someList) {
// do whatever
}
}

if (someList == null) {
return; // Or throw ex
}
for (Object object : someList) {
// do whatever
}

可能没有别的办法了。他们是否应该把它放在for构造本身中,如果它为空,那么不运行循环?

207613 次浏览

你可以写一个helper方法,如果你传入null,它会返回一个空序列:

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

然后使用:

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

我想我不会这么做,我通常会用第二种形式。特别地,“or throw ex”很重要——如果它真的不应该为空,你肯定应该抛出一个异常。你知道某物出了问题,但你不知道损坏的程度。提前中止。

你最好核实一下你的名单是从哪里来的。

您只需要一个空列表,因为空列表不会失败。

如果你从其他地方得到这个列表,不知道它是否正确,你可以创建一个实用程序方法,像这样使用它:

for( Object o : safe( list ) ) {
// do whatever
}

当然,safe将是:

public static List safe( List other ) {
return other == null ? Collections.EMPTY_LIST : other;
}

如果你从你实现的方法调用中得到List,那么不要返回null,而是返回一个空的List

如果你不能改变实现,那么你就只能使用null检查。如果它不应该是null,则抛出异常。

我不会选择返回空列表的helper方法,因为它有时可能有用,但这样你就会习惯在每次循环中调用它,可能会隐藏一些错误。

另一种有效防止for循环中出现空值的方法是用谷歌Guava的Optional<T>来包装你的集合,因为这样可以明确有效空集合的可能性,因为客户端会检查集合是否包含Optional.isPresent()

我已经修改了上面的答案,所以你不需要从对象强制转换

public static <T> List<T> safeClient( List<T> other ) {
return other == null ? Collections.EMPTY_LIST : other;
}

然后简单地调用列表

for (MyOwnObject ownObject : safeClient(someList)) {
// do whatever
}
< p >解释: MyOwnObject:如果List<Integer>,那么MyOwnObject在这种情况下将是Integer
for (Object object : someList) {


// do whatever
}  throws the null pointer exception.

数组使用commons-lang库中的ArrayUtils.nullToEmpty

for( Object o : ArrayUtils.nullToEmpty(list) ) {
// do whatever
}

这个功能存在于commons-lang库中,它包含在大多数Java项目中。

// ArrayUtils.nullToEmpty source code
public static Object[] nullToEmpty(final Object[] array) {
if (isEmpty(array)) {
return EMPTY_OBJECT_ARRAY;
}
return array;
}


// ArrayUtils.isEmpty source code
public static boolean isEmpty(final Object[] array) {
return array == null || array.length == 0;
}

这和@OscarRyz给出的答案是一样的,但是为了的咒语,我认为这是值得注意的。参见commons lang项目页面。这里是nullToEmpty API 文档

在你的项目中包含commons-lang(如果还没有)。

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>

不幸的是,commons-lang没有为List类型提供这个功能。在这种情况下,您必须使用前面提到的helper方法。

public static <E> List<E> nullToEmpty(List<E> list)
{
if(list == null || list.isEmpty())
{
return Collections.emptyList();
}
return list;
}

对于那些对编写自己的静态零安全方法不感兴趣的人,你可以使用:commons-lang的org.apache.commons.lang.ObjectUtils.defaultIfNull(Object, Object)。例如:

    for (final String item :
(List<String>)ObjectUtils.defaultIfNull(items, Collections.emptyList())) { ... }

ObjectUtils.defaultIfNull JavaDoc . defaultifnull

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

< p >用法:< br >

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

你可以用CollectionUtils.emptyIfNull对其他Collection类做同样的空安全检查。

Java 8 Optional:

for (Object object : Optional.ofNullable(someList).orElse(Collections.emptyList())) {
// do whatever
}

使用,CollectionUtils.isEmpty(Collection coll)方法,它是空安全的检查指定的集合是否为空。

对于这个import org.apache.commons.collections.CollectionUtils

Maven的依赖

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>