transient object[
] elementdata; //陣列容量
private int size; //實際存的元素個數
下文將會頻繁提及它們。
構造方法1:
public arraylist(int initialcapacity)
else
if(initialcapacity == 0)
else
}
傳入初始值,則直接生成乙個相應長度object陣列,此時size值是多少呢?
由於沒有賦值,則仍舊使用例項化時的值,即0。
構造方法2:
private static final object[
] defaultcapacity_empty_elementdata =;..
....
public arraylist(
)
將elementdata賦值為乙個空的object陣列,此時size=0;
構造方法3:
public arraylist(collection<? extends e> c)
else
}
傳入引數為乙個集合物件,首先將集合轉化為陣列,然後使用系統函式將該陣列copy到elementdata,即完成了賦值。此時size=elementdata.length 即集合物件的長度。
下面看下add方法:
private static final int default_capacity = 10;
private static final object[
] defaultcapacity_empty_elementdata =
;public boolean add(e e)
private void ensurecapacityinternal(int mincapacity)
private void ensureexplicitcapacity(int mincapacity)
private static int calculatecapacity(object[
] elementdata, int mincapacity)
return mincapacity;
}
增加乙個元素,首先確保容量正確。
將當前的size+1傳給calculatecapacity方法,如果陣列中不存在元素,取size+1與10相比的最大值,返回。否則直接返回size+1。
然後size+1的值傳入ensureexplicitcapacity 方法。如果該值大於實際目前陣列中元素個數,說明當前空間不夠了,需要擴容。否則除了增加modcount值後,不進行更多操作。modcount的作用我們稍後再說。
我們看下grow方法
private static final int max_array_size = integer.max_value - 8;
private void grow(int mincapacity)
private static int hugecapacity(int mincapacity)
首先對現有容量增加50%,去其與所需容量的最大值,如果該值大於integer.max_value - 8,則返回integer.max_value。所以一般所需容量小於現有容量的1.5倍,則使用1.5倍值,否則使用所需容量值,來新建陣列並將舊資料copy過來。
下面看下get 方法:
public e get(int index)
private void rangecheck(int index)
首先進行下標越界檢查,然後通過下標返回該元素。
下面看下set方法:
public e set(int index, e element)
可以看到是將index對應的值修改後,返回舊值。
remove方法
public e remove(int index)
可以看到是使用了 system.arraycopy將index後面的元素都copy往前移一位,將舊值返回。
可見刪除元素代價較大,而且元素越靠前,所要移動的資料就越多。
在指定位置新增元素add(int index, e element)
public void add(int index, e element)
可見是通過system.arraycopy,將資料進行copy,代價較高。
總結如下,例項化:用無參方法初始化時,只分配了乙個空陣列。使用容量引數初始化時,分配乙個引數大小的陣列。使用集合作為引數初始化時,將集合轉為陣列,copy到新陣列。
擴容機制是什麼?
當陣列元素為0時,第一次新增元素,容量變為10。此後add元素後所需容量大於現有容量時,進行擴容,擴容為1.5倍,如果還不夠,則使用當前元素總數為陣列長度。
arraylist的優缺點是什麼?
優點:可以根據下標快速找到元素(跟linkedlist相比),可以自動擴容(跟陣列相比)。
缺點:1.指定下標增刪資料,需要使用system.arraycopy 本地方法將該下標以後的資料進行大面積copy,效率較低。2.陣列中可能會存在空元素,造成一定的空間浪費。
arraylist使用場景有哪些?
適用於需要根據下標查詢的可變長陣列的情況。避免在需要對元素大量增刪情況下使用(對列尾部增刪無限制)。
以上。
ArrayList原始碼分析
arraylist是平時使用很多的乙個類,趁有時間,我也閱讀以下原始碼,以幫助自己加深理解。類的層次結構這裡就不列出了,主要分析一下原始碼部分,屬性部分 protected transient int modcount 0 這個屬性是從abstractlist繼承過來的,每次arraylist進行結...
ArrayList原始碼分析
有參建構函式傳入乙個int public arraylist int capacity 如果為0則返回空陣列,否則new 乙個capacity的陣列 array capacity 0 emptyarray.object new object capacity 無參建構函式 public arrayl...
ArrayList原始碼分析
最近因為擁抱變換,所以開始無奈的面試之路。因為在集合的原始碼分析上,出了些問題,所以這段時間,好好重新理一理常用的集合原始碼。版本基於jdk1.7 毫無疑問,提到常用集合。arraylist勢必是第乙個被搬出來的,因此我們就先拿它開刀了。arraylist的初始化,只有在第一次add的時候進行new...