增强的 for 循环中的空值检查
Posted
技术标签:
【中文标题】增强的 for 循环中的空值检查【英文标题】:Null check in an enhanced for loop 【发布时间】:2011-01-16 00:59:26 【问题描述】:在 Java 的 for 循环中防止 null 的最佳方法是什么?
这看起来很丑:
if (someList != null)
for (Object object : someList)
// do whatever
或者
if (someList == null)
return; // Or throw ex
for (Object object : someList)
// do whatever
可能没有其他方法。他们是否应该将其放入 for
构造本身,如果它为 null 则不运行循环?
【问题讨论】:
你最好还是扔一个 NPE。null
与空集合不同。
@GregMattes 2 月的问题与 10 月的问题是如何重复的?
只需要使用Collections.nonNullElementsIn(...):***.com/a/34913556/5637185
【参考方案1】:
使用 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给出的答案是一样的,但是为了DRY的口头禅,我相信还是值得注意的。请参阅commons-lang 项目页面。这是nullToEmpty
API documentation 和 source
Maven 条目以将 commons-lang
包含在您的项目中(如果还没有的话)。
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
很遗憾,commons-lang
没有为 List
类型提供此功能。在这种情况下,您必须使用前面提到的辅助方法。
public static <E> List<E> nullToEmpty(List<E> list)
if(list == null || list.isEmpty())
return Collections.emptyList();
return list;
【讨论】:
【参考方案2】:使用 CollectionUtils.isEmpty(Collection coll)
方法,该方法是 Null 安全的,检查指定集合是否为空。
为此import org.apache.commons.collections.CollectionUtils
。
Maven 依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>
【讨论】:
【参考方案3】:使用 Java 8 Optional
:
for (Object object : Optional.ofNullable(someList).orElse(Collections.emptyList()))
// do whatever
【讨论】:
它比简单的三元运算符如someList != null ? someList : Collections.emptyList()
更冗长,并且还创建并立即丢弃Optional
对象的实例。
这些怪物行如何比简单的 if(someList==null) 语句更优雅。让我们用一行写一个银行应用程序......【参考方案4】:
已经是 2017 年了,现在可以使用Apache Commons Collections4
用法:
for(Object obj : ListUtils.emptyIfNull(list1))
// Do your stuff
您可以使用 CollectionUtils.emptyIfNull
对其他 Collection 类执行相同的 null 安全检查。
【讨论】:
虽然会创建不必要的列表对象,但会起作用。 CollectionUtils.ifNotEmpty 可能更冗长但更有效和更快。没关系…… 2017 年我希望 List.emptyIfNull(list1) @Lawrence,该方法不创建新的列表对象,它在内部使用Collections.emptyList()
,而它又总是返回相同的预分配空的不可修改的列表。
如果你调用 myobject.getCompanies().getAddresses() 并且都返回一个 List 并且两者都可以为 null 怎么办?【参考方案5】:
对于任何对编写自己的静态空安全方法不感兴趣的人,您可以使用:commons-lang 的org.apache.commons.lang.ObjectUtils.defaultIfNull(Object, Object)
。例如:
for (final String item :
(List<String>)ObjectUtils.defaultIfNull(items, Collections.emptyList())) ...
ObjectUtils.defaultIfNull JavaDoc
【讨论】:
对我来说,这个答案是最优雅的 另一种使用Java原生Objects
类的类似方法是Objects.requireNonNullElse(itemsList, new ArrayList<String>())
【参考方案6】:
for (Object object : someList)
// do whatever
throws the null pointer exception.
【讨论】:
【参考方案7】:我已经修改了上面的答案,所以你不需要从 Object 投射
public static <T> List<T> safeClient( List<T> other )
return other == null ? Collections.EMPTY_LIST : other;
然后简单地调用列表
for (MyOwnObject ownObject : safeClient(someList))
// do whatever
说明:
MyOwnObject:如果List<Integer>
,那么在这种情况下,MyOwnObject 将是 Integer。
【讨论】:
【参考方案8】:在 for 循环中有效防止 null 的另一种方法是使用 Google Guava 的 Optional<T>
包装您的集合,因为人们希望这样可以明确有效地为空集合的可能性,因为客户需要检查是否该集合与Optional.isPresent()
一起出现。
【讨论】:
【参考方案9】:您最好验证您从哪里获得该列表。
你只需要一个空列表,因为一个空列表不会失败。
如果你从其他地方得到这个列表并且不知道它是否可以,你可以创建一个实用方法并像这样使用它:
for( Object o : safe( list ) )
// do whatever
当然safe
是:
public static List safe( List other )
return other == null ? Collections.EMPTY_LIST : other;
【讨论】:
请注意,Collections.emptyList() 将避免分配额外的对象 (IIRC)。 @Jon:我一直在问自己,emptyList
java.sun.com/j2se/1.5.0/docs/api/java/util/…IIRC 有什么用?
IIRC = "如果我没记错的话"。是的,所有对 Collections.emptyList() 的调用都会返回一个单例实例。
这...实际上并没有回答这个问题。为什么它被接受?
@ChristopherWirt 因为它确实回答了这个问题:D【参考方案10】:
如果你传入 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”很重要——如果它真的不应该为空,你肯定应该抛出一个异常。您知道某事出了问题,但您不知道损坏的程度。提前中止。
【讨论】:
我会将 IterableemptyIfNull
的返回类型是Iterable<T>
- 在Iterator<T>
上有不幸的remove
方法,但这是它唯一可变的方面(如果你有一个空集合,你为什么要尝试从中删除任何内容?)不清楚您在这里反对什么。【参考方案11】:
如果您从您实现的方法调用中获得 List
,则不要返回 null
,而是返回一个空的 List
。
如果您无法更改实现,那么您将无法使用null
检查。如果不应该是null
,则抛出异常。
我不会使用返回空列表的辅助方法,因为它有时可能很有用,但你会习惯在每个循环中调用它,可能会隐藏一些错误。
【讨论】:
以上是关于增强的 for 循环中的空值检查的主要内容,如果未能解决你的问题,请参考以下文章
Java中的增强for循环怎么用?for()中的参数是啥意思
在java中,新循环,也就是增强for循环怎么用?是啥格式?