2015-08-20 27 views
1

考慮下面的兩段代碼:ArrayList中的add()的行爲方式

ArrayList<Integer> list = new ArrayList<Integer>(); 
list.add(0); 
for (int i=1; i<10; i++) 
    list.add(i); 

ArrayList<Integer> list = new ArrayList<Integer>(); 
for (int i=1; i<10; i++) 
    list.add(i); 
list.add(0,0); 

我真的想知道是否有在這兩種情況的任何性能差異?我在想的是ArrayList實際上是一個Object [] ...所以第二個代碼片段需要將原始數組複製到某個地方,然後在位置0創建一個新的'0'...所以我認爲第一種方法確實比較好?

+1

在這個級別上擔心性能差異確實是非常沒有意義的。如果你有一個完整的項目-AND-分析表明你在模塊中存在性能問題... - 那麼考慮微優化是合理的。上面代碼片段的差異可能會很小。 – scottb

回答

8

...所以第二個代碼片段需要將原來的陣列複製到某個地方,然後創建在位置0一個新的「0」 ......

它不會必須分配一個,如果它有足夠的空間在其當前的一個(使用該代碼,它將使用Oracle的實現  — 只是,它默認初始容量爲10)。但它不得不攪亂。

...所以我覺得第一種方法確實比較好?

當然,也是你給的原因。第二個塊只是不必要地讓ArrayList在底層數組中移動。

(不,它很可能多大關係,除非這是一個非常緊密循環中運行了數百萬次......不過還是。)

2

第一個選項是更好的。一般來說,順序訪問速度更快,但第一個例子也是更清晰的恕我直言。

您可以查看源,如果你真的想知道,但是

list.add(0, 0); 

洗牌底層數組下來的元素。它只會創建一個新的陣列,如果它沒有足夠的容量,就像list.add(i)必須做的那樣。

0

第二種方法將改變Arraylist中的其他元素,從而引入性能問題。見this doc link。只有在沒有空間的情況下,它纔會創建新的陣列。

0

第一種方法只是更好的做法,但在這種情況下,兩者都沒有明顯的優勢。儘管其他回答說,ArrayLists不需要花時間插入一個元素,無論它在哪裏。也就是說,在開始處插入0是恆定的。請注意,如果要插入多個元素,則時間爲O(n),其中n是要插入的項目數。

當我跑這兩個代碼段的一些測試,這裏的結果:

794913915 
703911773 

838856889 
942264566 

所以你可以看到,當你插入一個元素,它並不重要。注意:此測試插入100項目而不是10,但10的結果相同。然而,如果我們運行同樣的測試,除了第一種情況下首先將100項目和第二種情況在列表的開頭插入100項目後,這裏的結果:

1316759001 
8390794221 

的「更好的做法」的方法需要時間少得多。

相關問題