2009-04-07 80 views
6

如果你有一個集合的實例,這樣說:什麼傳遞給數組實例方法toArray(T [] a)方法?

Collection<String> addresses = new ArrayList<String>(); 

這當中,然後被一幫價值觀,這是「最好」的方式,如果有的話,儘量使用的填充toArray()方法而不需要類型轉換?

String[] addressesArray = addresses.toArray(new String[] {}); 
String[] addressesArray = addresses.toArray(new String[0]); 
String[] addressesArray = addresses.toArray(new String[addresses.size()]); 
String[] addressesArray = addresses.toArray(new String[addresses.size() + 5]); 

前兩者之間是否有語義上的區別?第三最有效率?第四個效率低於第三個?

回答

7

根據a findbugs report,這是最有效的:

String[] addressesArray = addresses.toArray(new String[addresses.size()]); 

我相信他們;)

+2

這是不正確的,根據@AlekseyShipilev http://shipilev.net/blog/2016/arrays-wisdom-ancients/ – 2016-02-19 20:21:26

0

這在List界面的Javadoc被記載:

如果列表適合與空間指定的陣列中剩餘空間(即,該陣列具有比列表多個元件),該元件陣列中的緊隨列表結尾後立即設置爲空。 (這是在確定只有當呼叫方知道列表不包含任何空元素的列表的長度是有用的。)

+0

它是有道理的,如果ArrayList的大小是5,並且您傳遞給Array()一個新的大小爲10的String數組,那麼它將被調整大小,但我仍然不知道哪個或多或少是正確/高效的。 – 2009-04-07 21:25:58

+0

它不調整數組的大小,它只是將列表末尾的元素設置爲null。 – 2009-04-07 21:38:29

0

你對前兩條語句的效果是一樣的。

第三個是最有效的,因爲如果你的元素不適合數組,你會爲你創建一個新的數組。

3

如果您選擇不相信他人,或者只是想自己檢查,您可以查看source for java.util.ArrayList(張貼該來源可能違反了一些許可證,我很高興我只是鏈接到它)。當您下載Sun's JDK時,您還可以獲得所有源代碼的副本)。

審查源代碼<T> T[] toArray(T[] a);後很明顯:

String[] addressesArray = addresses.toArray(new String[addresses.size()]); 

是做到這一點的最快方式。

顯然,你不能總是花時間閱讀和理解源代碼,有時最好的選擇並不總是顯而易見的,但是對於更簡單的方法,閱讀源代碼可能非常有用。

5

對於我的錢

String[] addressesArray = addresses.toArray(new String[0]); 

是最簡單的,容易出錯最少,因此 「最好的」。它還具有相同的代碼適用於併發/同步集合的優點。你將不得不在一些真正的低級別,大量使用的代碼中忽略不計的性能差異來產生任何影響。

你經常看到分配給static final,以避免在每次執行分配一個空數組。顯然,事實證明,由於「優化」(配置確實非常快),性能會下降。

更新:轉出,這是比使用大小的數組更快。http://shipilev.net/blog/2016/arrays-wisdom-ancients/tl; dr:反射是不涉及慢方法查找的普通類型,如果可以確定所有元素都將被寫入(或數組變爲不可訪問),則可以丟棄數組的零點。

+2

+1的文章發現併發問題。我曾經在代碼中遇到過這個問題:http://github.com/orfjackal/dimdwarf/blob/0d1a0897821a4e0e557a1390a7252a8580d2ec95/dimdwarf-core/src/main/java/net/orfjackal/dimdwarf/scheduler/TaskThreadPool.java#L111 -116 – 2009-04-08 14:27:57

1

這主要是理論上的意義,但如果該列表是空的時候,你可以重用一個長度爲零的數組:

private static final String[] EMPTY_STRING_ARRAY = {}; 
... 
String[] addressesArray = addresses.toArray(EMPTY_STRING_ARRAY); 

由於零長度數組是不可變的(不像非零長度數組),它們可以存儲並重用。