2010-02-12 134 views
137

防止Java中的for循環null的最佳方法是什麼?空值檢查增強for循環

這似乎難看:

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

或者

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

有可能不是任何其他方式。他們是否應該將它放在for構造本身中,如果它爲空,那麼不要運行循環?

+2

你可能最好拋出NPE。 'null'與空集合不同。 – 2010-02-12 08:35:39

+6

@GregMattes 2月問題如何與10月問題重複? – Val 2013-09-09 08:47:58

+1

只需要使用Collections.nonNullElementsIn(...):http://stackoverflow.com/a/34913556/5637185 – 2016-01-21 01:00:17

回答

196

您應該更好地驗證從哪裏獲取該列表。

空列表是你需要的,因爲空列表不會失敗。

如果你從別的地方獲得這個名單,不知道這是否是好不好,你可以創建一個實用的方法,並使用它像這樣:

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

當然safe,並且將是:

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

請注意Collections.emptyList()將避免分配額外的對象(IIRC)。 – 2010-02-12 06:31:45

+7

@Jon:我一直在問自己,那個'emptyList'的用法是什麼http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collections.html#emptyList( )什麼是IIRC? – OscarRyz 2010-02-12 06:34:02

+10

IIRC =「如果我記得正確」。是的,所有對Collections.emptyList()的調用都會返回一個單例實例。 – ColinD 2010-02-12 06:40:24

81

你可能會寫一個返回一個空序列的輔助方法,如果你傳入null,則:

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

然後使用:

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

我不認爲我會真的這樣做雖然 - 我通常會使用你的第二種形式。特別是,「或拋出」是重要的 - 如果它真的不應該是空的,你一定要拋出異常。你知道東西出了問題,但你不知道損壞的程度。提前中止。

+3

我會改變可迭代的列表參數爲可迭代的,因爲不是每個迭代都是一個列表。 – Lombo 2010-02-12 06:35:24

+0

@limbo:是的,很好的電話。 – 2010-02-12 06:58:10

+0

小心使用這種方法:因爲使用了Collections類,使用這個方法涉及到你的列表te是不可變的 – Tanorix 2017-04-26 16:34:48

6

如果您獲得的List從您實現一個方法調用,那麼不返回null,返回一個空List

如果您無法更改執行方式,那麼您將被卡在null檢查中。如果它不應該是null,那麼拋出異常。

我不會去幫助方法返回一個空列表,因爲它可能會有用一些時間,但然後你會習慣在你做的每個循環中調用它可能隱藏一些錯誤。

1

有效防範for循環中的null的另一種方法是用Google Guava的Optional<T>包裝您的收藏集,因爲這可能會導致有效地清空收藏夾,因爲客戶端應該檢查收集與Optional.isPresent()存在。

3

我已經修改了上面的回答,所以你並不需要通過

for (MyOwnObject ownObject : safeClient(someList)) { 
    // do whatever 
} 

釋從Object

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

投,然後簡單地調用列表: MyOwnObject:如果List<Integer>然後在這種情況下,MyOwnObject將爲Integer。

-2
for (Object object : someList) { 

    // do whatever 
} throws the null pointer exception. 
+6

關於代碼的任何解釋? – Ian 2016-05-10 13:11:37

5

TL; DR使用ArrayUtils.nullToEmptycommons-lang庫陣列

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 documentationsource

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; 
} 
1

對於任何不感興趣編寫自己的靜態無效安全方法的人,您可以使用:commons-lang's org.apache.commons.lang.ObjectUtils.defaultIfNull(Object, Object)。例如:

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

ObjectUtils.defaultIfNull JavaDoc

+0

對我來說,這個答案是最優雅的 – 2016-11-11 16:45:47

18

它已經2017年了,你現在可以使用Apache Commons Collections4

用法:

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

你可以做同樣的空安全檢查到CollectionUtils.emptyIfNull的其他收藏類。

+2

雖然會創建不必要的列表對象。 CollectionUtils.ifNotEmpty可能更詳細,但更高效和更快。不是說這很重要... – Lawrence 2017-08-29 10:07:19

+2

在2017年,我期望List.emptyIfNull(list1) – Dima 2017-12-04 20:37:44

+1

@勞倫斯,該方法不會創建新的列表對象,它在內部使用'Collections.emptyList()總是返回相同的預分配空白不可修改列表。 – 2018-02-27 06:33:48

3

與Java 8 Optional

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

它比簡單的三元運算符更像'someList!= null? someList:Collections.emptyList()'並且還創建並立即拋出'Optional'對象的實例。 – 2018-02-27 06:44:12

0

使用,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>