問題是這樣產生的,網上一哥們發了一個面試題:
ListA 裏面有 1 2 3
ListB裏面有 4 5 6
讓ListA變成 1 2 3 4 5 6
我覺得很簡單 ,就說用for循環遍歷 添加就好了。結果面試官說
答案是使用addAll方法,因爲這樣效率高:
我表示很費解,於是查閱了資料。
得出以下結論:
在小數據量時,for循環效率高,大數據量時addAll方法效率高:
原因如下:
ArrayList的addAll的實現爲:
public boolean addAll(Collection c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacity(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
很顯然。。在拷貝數組時使用了
arraycopy 這個方法。這個方法是使用拷貝內存的做法 ,效率比遍歷數組塊很多。
首先找到數據源 然後將該段內存拷貝。
當然值得注意的是,這個函數中還使用了toArray方法,這個方法是 要遍歷操作的
但是如果需要多次遍歷,那麼addAll還是在性能上會獲取優勢的. .
下面是網上的一個測試 在20組數據時 還是 for效率高,但是在大數據量的時候 arraycopy 方法就明顯佔優勢了。
http://www.exam8.com/computer/djks/dj2/Java/ziliao/200810/1314435.htmlhttp://www.exam8.com/computer/djks/dj2/Java/ziliao/200810/1314435.html
另外:
arraycopy的定義是這樣的
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos,int length);
native關鍵字的意思是 這個函數的源碼在JDK中沒有的。但是他調用的是本地計算機中的函數
這個函數是C,或者C++寫完的,編譯成DLL。 java調用。所以效率比for循環要塊。
綜上所述 :爲什麼在大數據量時使用addall方法效率快?
1.使用內存拷貝,移動數據。
2.本地函數,執行效率高。
那小數據量時呢?
以上2點都不明顯,並且首先要調用toArray方法,在小數據量時,效果沒有for來的好。