arraylist可以實現容量的自適應的增加,通過閱讀源**,對這個機制進行一下簡單的分析。
首先,arraylist有乙個初始的預設大小,為10.
private static final int default_capacity = 10;
從add方法為入口
public boolean add(e e)
可見,在新增元素之前,會先呼叫ensurecapacityinternal這個方法,那就再進到這個這個方法中去。
private void ensurecapacityinternal(int mincapacity)
ensureexplicitcapacity(mincapacity);
}首先,看看陣列是否為空,如果是,就將default_capacity和mincapacity的較大的乙個作為初始大小賦值給mincapacity ,default_capacity是10,mincapacity就是add方法中傳入的size + 1。
如果陣列不為空,就直接執行ensureexplicitcapacity方法。ensureexplicitcapacity方法的實現如下:
private void ensureexplicitcapacity(int mincapacity)
在這個方法裡,會比較mincapacity 與elementdata.length 的大小。當第一次插入值時,由於mincapacity 一定大於等於10,而
elementdata.length是0,所以會去繼續執行grow方法,那就繼續進入到這個方法中去。grow方法的實現如下:
private void grow(int mincapacity)
這個方法首先計算出乙個容量,大小為oldcapacity + (oldcapacity >> 1)。即elementdata陣列長度的1.5倍。再從mincapacity 和
這個容量中取較大的值作為擴容後的新的陣列的大小。
這時,會出現兩種情況:
一. 新的容量小於陣列的最大值max_array_size ,即
private static final int max_array_size = integer.max_value - 8;
最大的容量之所以設為integer.max_value - 8,在定義上方的注釋中已經說了,大概是一些jvm實現時,會在陣列的前面放一些額外的資料,再加上陣列中的資料大小,有可能超過一次能申請的整塊記憶體的大小上限,出現outofmemoryerror。
二. 新的容量大於陣列的最大值
max_array_size
這時,又會進入另乙個方法hugecapacity
private static int hugecapacity(int mincapacity)
會對mincapacity 和 max_array_size進行比較,mincapacity 大的話,就將integer.max_value 作為新陣列的大小,否則將max_array_size作為陣列的大小。
最後,就把原來陣列的資料複製到新的陣列中。呼叫了
arrays的copyof方法。內部是system的arraycopy方法,由於是native方法,所以效率較高。
通過分析可以發現,arraylist的擴容會產生乙個新的陣列,將原來陣列的值複製到新的陣列中。會消耗一定的資源。所以我們初始化arraylist時,最好可以估算乙個初始的大小。
ArrayList的動態擴容
arraylist可以實現容量的自適應的增加,通過閱讀源 對這個機制進行一下簡單的分析。首先,arraylist有乙個初始的預設大小,為10.private static final int default capacity 10 從add方法為入口 public boolean add e e 可...
ArrayList的動態擴容機制
一般問的時候應該是用jdk1.6回答 jdk1.7之後也要知道 初始化 有三種方式預設的構造器,將會以預設的大小來初始化內部的陣列 public arraylist 用乙個icollection物件來構造,並將該集合的元素新增到arraylist public arraylist collectio...
ArrayList的動態擴容機制
先來看一道筆試題 下面的arraylist會擴容幾次?arraylistarraylist new arraylist 20 我們先看一下原始碼的動態擴容機制是如何實現的。下面以jdk1.7為例 private void grow int mincapacity 通過下面這一行 int newcap...