1. 程式人生 > >jdk 1.8下 java ArrayList 添加元素解析

jdk 1.8下 java ArrayList 添加元素解析

正常 信息 jdk 1.7 integer 原來 logs tac pyo 最小

轉載請註明http://www.cnblogs.com/majianming/p/8006452.html

有人問我,java ArrayList底層是怎麽實現的?我就回答數組,他再問我,那它是怎麽實現數組的添加的呢?我也不知道,就不敢回答了。

回來趕緊看了一下java實現,明確的是ArrayList底層的確是用數組實現的,但是怎麽實現數組的擴容的呢?

簡單來說,就是創建一個新的比原來大的數組,把原來所有的元素復制到新的數組,然後添加新的數組進去


先從無參構造函數開始,無參構造函數創建了一個容量為0的空數組(這裏要註意,在jdk1.8時采用的是創建空數組,在1.7還是創建了一個容量為10的數組,源碼見附錄1,2,這裏以1.8為例

然後就可以開始調用add方法添加元素,這裏先以public boolean add(E e)方法為例

  1. 計算最小容量:判斷是不是第一次添加,準確來說是不是一個空數組。如果是一個空數組,那麽設置初始化大小(即最小容量)為10,如果不是,那麽在原來基礎上大小+1。
  2. 判斷是否需要擴容:判斷最小容量是不是大於數組長度(至少大1),如果是,進行第3步。為什麽有這個判斷?是最小容量是數組可以存放的元素個數,而數組長度是實際上存放的個數,那麽就會出現數組還沒放滿的情況,比如第二次添加時,數組容量為10(第一次初始化時設置為10),元素加上新增加的只有兩個,是不需要進行第3,4步的
  3. 擴容計算:
    1. 取得已有元素的個數,準備設置新的容量為原來元素個數的1.5倍
    2. 將1中的新容量和最小容量相對比,取大的(所以初始化時原來元素的1.5倍為0小於最小容量10,設置為10)
    3. 將2中計算結果與Integer.MAX_VALUE - 8對比(為啥是-8 ,doc上是說明了一些虛擬機實現需要多存一些頭信息,為了防止oom,其他沒有說明,在stackoverflow上說明了為了存下數組的最大大小2,147,483,648所以需要(見附錄3))還大,那就沒辦法了,只能設置為Integer.MAX_VALUE。也就是說正常情況下數組最大容量為下最大值減8,否則就是最大值。這個時候放不下那就只能拋異常了唄!
  4. 復制舊元素到新數組:上一步計算的只是一個值,沒有對原來的進行修改,也沒有創建新的數組。接下來使用Arrays.copyOf將原來數組的所有元素復制到新數組(以最小容量創建的),並返回
  5. 把添加的元素添加到新返回的數組最後,長度+1


附錄

  1. jdk 1.7 ArrayList
  2. jdk 1.8 ArrayList
  3. 為什麽-8

參考

Java中ArrayList源碼淺析


設定

jdk:1.8_102

轉載請註明http://www.cnblogs.com/majianming/p/8006452.html

jdk 1.8下 java ArrayList 添加元素解析