空检查增强for循环
在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 }
可能没有其他办法。 他们是否应该把它放在构造本身,如果它是空的,那么不要运行循环?
你应该更好地validation你从哪里得到的名单。
一个空列表是你所需要的,因为一个空列表不会失败。
如果你从其他地方得到这个列表,不知道是否可以,你可以创build一个实用的方法,并像这样使用它:
for( Object o : safe( list ) ) { // do whatever }
当然, safe
将是:
public static List safe( List other ) { return other == null ? Collections.EMPTY_LIST : other; }
如果你传入null,你可能会编写一个返回空序列的帮助器方法:
public static <T> Iterable<T> emptyIfNull(Iterable<T> iterable) { return iterable == null ? Collections.<T>emptyList() : iterable; }
然后使用:
for (Object object : emptyIfNull(someList)) { }
我不认为我真的这样做 – 我通常会使用你的第二种forms。 特别是,“或抛出”是重要的 – 如果它不应该是空的,你一定要抛出exception。 你知道有什么地方出了问题,但是你不知道损坏的程度。 提前中止。
现在已经是2017年了,现在可以使用Apache Commons Collections4了
用法:
for(Object obj : ListUtils.emptyIfNull(list1)){ // Do your stuff }
您可以使用CollectionUtils.emptyIfNull
对其他Collection类执行相同的空安全检查。
如果您从您实现的方法调用中获取该List
,则不要返回null
,并返回一个空List
。
如果你不能改变实现,那么你坚持使用null
检查。 如果不应该为null
,则抛出exception。
我不会去帮助方法返回一个空的列表,因为它可能会有用的一些时间,但是你会习惯在你做的每个循环中调用它可能隐藏一些错误。
我已经修改了上面的答案,所以你不需要从Object投射
public static <T> List<T> safeClient( List<T> other ) { return other == null ? Collections.EMPTY_LIST : other; }
然后简单地调用List
for (MyOwnObject ownObject : safeClient(someList)) { // do whatever }
解释:MyOwnObject:如果List<Integer>
那么MyOwnObject在这种情况下将是Integer。
TL; DR使用来自commons-lang
数组库的ArrayUtils.nullToEmpty
for( Object o : ArrayUtils.nullToEmpty(list) ) { // do whatever }
该function存在于大多数Java项目中的commons-lang
库中。
// 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 文档和源代码
如果Maven项目尚未包含commons-lang
,请将其添加到项目中。
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency>
不幸的是, commons-lang
不提供List
types的这个function。 在这种情况下,您将不得不使用前面提到的帮助方法。
public static <E> List<E> nullToEmpty(List<E> list) { if(list == null || list.isEmpty()) { return Collections.emptyList(); } return list; }
使用Java 8 Optional
:
for (Object object : Optional.ofNullable(someList).orElse(Collections.emptyList())) { // do whatever }
另一种有效地防止for循环中的空值的方法是用Google Guava的Optional<T>
包装你的集合,因为希望客户端可以检查集合与Optional.isPresent()
。
对于任何对编写自己的静态null安全方法不感兴趣的人,可以使用:commons-lang的org.apache.commons.lang.ObjectUtils.defaultIfNull(Object, Object)
。 例如:
for (final String item : (List<String>)ObjectUtils.defaultIfNull(items, Collections.emptyList())) { ... }
ObjectUtils.defaultIfNull JavaDoc
使用CollectionUtils.isEmpty(Collection coll)
方法,如果指定的collection是空的,则为Null-safe检查。
为此import org.apache.commons.collections.CollectionUtils
。
Maven依赖
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>4.0</version> </dependency>
for (Object object : someList) { // do whatever } throws the null pointer exception.