Java中ArrayList 自動擴容的內存上的具體過程是怎樣的?為了答這個題,又去溫習了一遍ArrayList的源碼,姑且說下。。

JAVA中的很多基本數據結構都有動態擴容機制,比如hashMap,arraylist,之前說過了hashMap的擴容,現在說下arraylist的。。

arraylist的擴容發生在add()方法過程中,如下圖,先返回一個最新的size+1的數組,然后把加入的元素放入其中,如下圖:

Java 中 ArrayList 自動擴容

上圖中的ensureCapacityInternal方法,主要是調用grow()方法,如下所示:

Java 中 ArrayList 自動擴容

在grow方法中定義了一個新的數組容量newCapacity=oldCapacity +(oldCapacity >>1),>>符號代表左移一位,也就是除以2,換句話說新的容量擴容變為原來的1.5倍大小!然后將舊的所有元素通過使用Arrays.copyOf方法復制到新的數組中!

Java 中 ArrayList 自動擴容

如下面的代碼所示:Arrays.copyOf方法內部是調用的native方法System.arraycopy();這個方法會在內存中創建一個新的數組,所以在擴容之后,返回的通常是一個新創建的數組,來替換原來的數組

Java 中 ArrayList 自動擴容

一般來說,list的自動擴容有兩個方面的問題:

①,性能:每次擴容都需要創建新的數組,并且復制原有數據,如果一個arraylist存儲的數據過大,也就代表著擴容次數多,而且對內存有很大的占用!

②,線程不安全:因為調用add方法中,有++操作,可能會在多線程環境下引起數組中元素為空,數據被覆蓋等問題,所以在多線程環境下,arrayList需要改為Collections.synchonizedList()來獲取一個安全的list實例!

Java 中 ArrayList 自動擴容

arrayList和hashMap可以說是JAVA開發人員遇到的最多的兩個數據結構,但是往往有很多容易忽略的小坑,所以基礎學習很重要。