面試中常常問到的問題之一就是List的擴容機制了,他是怎麼作到擴容的,你們都能答出來底層是數組,複製一個數組來擴容,可是再具體一點來講,你們就不知道該怎麼說了,若是不看源碼說這麼多確實就差很少了,可是看了源碼你會說的更多,更詳細,更具體,本篇主要看的是jdk1.8 至於其餘版本大同小異,看看就知道了,言歸正傳html
總的來講就是分兩步:一、擴容java
把原來的數組複製到另外一個內存空間更大的數組中面試
二、添加元素數組
把新元素添加到擴容之後的數組中源碼分析
先把ArrayList中定義的一些屬性貼出來方便下面源碼分析ui
分析以前咱們先看一下ArrayList的兩個構造方法this
ArrayList()
ArrayList(int initialCapacity)
無參構造:
public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } 帶參構造:
public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
在無參構造中,咱們看到了在用無參構造來建立對象的時候其實就是建立了一個空數組,長度爲0spa
在有參構造中,傳入的參數是正整數就按照傳入的參數來肯定建立數組的大小,不然異常code
接下來咱們來看擴容,擴容的方法就是 add(E e)htm
貼上源碼
看,其實add方法就兩步,第一步:增長長度,第二步:添加元素到數組,第二步沒什麼說的,咱們看看ensureCapacityInternal(int minCapacity)這個增長長度的方法
這個地方咱們看到了,若是在添加的時候遠數組是空的,就直接給一個10的長度,不然的話就加一
if (minCapacity - elementData.length > 0)
grow(minCapacity);
經過這個地方是真正的增長長度,當須要的長度大於原來數組長度的時候就須要擴容了,相反的則不須要擴容
這個地方注意這一句
int newCapacity = oldCapacity + (oldCapacity >> 1);
oldCapacity >> 1 右移運算符 原來長度的一半 再加上原長度也就是每次擴容是原來的1.5倍
以前的全部都是肯定新數組的長度,肯定以後就是把老數組copy到新數組中,這樣數組的擴容就結束了
以上的一切都是ArrayList擴容的第一步,第二步就沒啥說的了,就是把須要添加的元素添加到數組的最後一位
源碼本不難,想的多看的少了就難了