2011-04-05 32 views

回答

202

主要區別在於Collections.emptyList()返回不可變的列表,即無法添加元素的列表。

在極少數情況下,您想要修改返回的列表,因此這不會是一個選項。

我想說,只要合同(文檔)沒有明確指出不同的狀態,返回一個不可變列表就完全沒問題(甚至是首選方法)。


此外,這種方法的emptyList()might not create a new object with each call.

實現不需要爲每次調用創建一個單獨的列表對象。使用這種方法很可能會使用類似命名的字段。 (與此不同的方法,該字段不提供類型安全。)

emptyList實現如下所示:

public static final <T> List<T> emptyList() { 
    return (List<T>) EMPTY_LIST; 
} 

所以,如果你的方法(該方法返回一個空列表)被稱爲非常頻繁,這種方法甚至可以讓你在CPU和內存方面有更好的性能。

+3

所以,將'Collections.emptyList()'更適合讓我們說,錯誤檢查之類的? – mre 2011-04-05 13:05:43

+3

是的,我會這麼說。 – aioobe 2011-04-05 13:07:02

+1

API客戶端將無法獲得通過''返回'的Collections.emptyList()代替'null' NullPointerException'。 – realPK 2016-07-11 02:54:07

24

Collections.emptyList是不可變的,所以這兩個版本之間存在差異,因此您必須考慮返回值的用戶。

返回new ArrayList<Foo>總是會創建一個新的對象實例,因此它只會產生很小的額外費用,因此可能會給您一個使用Collections.emptyList的理由。我喜歡使用emptyList,因爲它更具可讀性。

4

我會Collections.emptyList()去,如果返回的列表中沒有被以任何方式修改(如列表是不可改變的),否則我會去與選項2

Collections.emptyList()的好處是,同樣的靜態實例每次都會返回,因此每個調用都不會創建實例。

40

與Java 5.0開始,你可以在容器指定元素的類型:

Collections.<Foo>emptyList() 

我與其他響應爲要返回保持爲空,空單的情況下,你應該使用同意這種方法。

+22

與Java 7開始,您可以讓編譯器推斷目標類型的泛型方法調用的參數類型:'名單列表= Collections.emptyList()' – 2015-05-15 20:16:15

2

使用Collections.emptyList()如果你想確保返回的列表永遠不會被修改。這是返回上調用的emptyList():

/** 
* The empty list (immutable). 
*/ 
public static final List EMPTY_LIST = new EmptyList(); 
+3

什麼新鮮事相比,早期的答案,不是嗎? – kleopatra 2012-10-28 13:24:01

+0

我到了這裏試圖找出是否調用'Collections.emptyList()'有建設成本。查看實現細節(儘管可能在所有JVM上不一樣)確認它沒有。 @Atul,JVM是從哪裏來的? – wjl 2013-08-29 14:36:49

1

給出的答案強調emptyList()返回一個不可改變的List但不給替代品的事實。構造函數ArrayList(int initialCapacity)特殊情況0所以返回的new ArrayList<>(0)代替new ArrayList<>()也可能是一個可行的解決方案:

/** 
* Shared empty array instance used for empty instances. 
*/ 
private static final Object[] EMPTY_ELEMENTDATA = {}; 

[...]

/** 
* Constructs an empty list with the specified initial capacity. 
* 
* @param initialCapacity the initial capacity of the list 
* @throws IllegalArgumentException if the specified initial capacity 
*   is negative 
*/ 
public ArrayList(int initialCapacity) { 
    if (initialCapacity > 0) { 
     this.elementData = new Object[initialCapacity]; 
    } else if (initialCapacity == 0) { 
     this.elementData = EMPTY_ELEMENTDATA; 
    } else { 
     throw new IllegalArgumentException("Illegal Capacity: "+ 
              initialCapacity); 
    } 
} 

(從Java 1.8.0_72源)

+0

我不同意你的方法。您在初始化時節省了一些內存和CPU,但是如果您返回的列表經歷過修改,那麼當列表重新分配一個新陣列時,就會失去這個時間。如果很多的元素被添加到列表中隨着時間的推移,這可能會堆積成更大的性能瓶頸所致[慢得多的速度增長(http://grepcode.com/file/repository.grepcode.com/java的/root/jdk/openjdk/6-b14/java/util/ArrayList.java#ArrayList.ensureCapacity%28int%29)。我更喜歡堅持不可修改的空列表或可用,可修改列表的約定。 – 2016-02-24 19:05:16

+1

正如我試圖強調我的措辭(_可能可行):這一切都取決於您的使用情況。我通常會選擇返回可變或不可變集合,而不是混合取決於它們是否爲空。並反擊了「慢很多要求」:[這裏](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/ArrayList.java# ArrayList.ensureCapacityInternal%28int%29)是當前的實現。 – 2016-02-24 20:29:26

+0

呵呵,看看我引用JDK 2主要版本過時了。所以java8完全避免了從初始大小0跳到默認容量的瓶頸。對不起,我錯了。 – 2016-02-24 20:50:49

5

儘管謹慎。如果你將返回Collections.emptyList(),然後嘗試做一些改變它像add()或水木清華那樣,你也會有一個UnsupportedOperationException()因爲Collections.emptyList()返回不可變對象。