ArrayList原始碼步步分析

2021-10-10 13:40:55 字數 1991 閱讀 4935

以下全都是基於jdk1.8

首先從集合底層實現說起

private static final int default_capacity = 10;

transient object elementdata; // non-private to simplify nested class access

arraylist底層是乙個object陣列,並且預設長度是10,確定是10嗎?如果是的話,那麼這個10是什麼時候加上去的?我們先來看一看arraylist的無參構造。

public arraylist()
可以看到這個無參構造,並沒有初始化arraylist的大小,或者說初始化後陣列的長度是0。再看一下有參構造和add方法,為什麼要結合著看?我舉乙個例子,就知道了

public arraylist(int initialcapacity)  else if (initialcapacity == 0)  else 

}

接著看一下add方法

public boolean add(e e) 

private void ensurecapacityinternal(int mincapacity)

private void ensureexplicitcapacity(int mincapacity)

有參構造中可以修改arraylist的預設長度,如下面的例子,我新建乙個預設長度為2的arraylist,然後新增4個元素,在第10行打斷點,進入除錯,看看會發生什麼。

可以看到,在新增第三個元素的時候擴容了,那麼擴容了多少呢?接著進入grow方法

擴容的數量是,之前陣列的長度的一半,也就是擴容後的長度是之前長度的1.5倍,看到這裡我突然有個疑問——首先看上面一張圖。在判斷是否要擴容的時候,已經確定了加上當前元素之後,會超過當前陣列的長度,但是在grow方法裡面還多了一步newcapacity-mincapacity的判斷,新陣列的長度居然會比所需最小陣列(oldcapacity + 1 > oldcapacity/2 + oldcapacity),說明oldcapacity/2 < 1,也就是說oldcapacity=1

為了驗證我的推斷,我修改預設長度為1,然後再第9行打斷點。

debug一下,果然是這樣,我的推斷是正確的

但是回過來思考一開始的問題,arraylist的預設長度是10?但是初始化的時候是0啊!抓住這個10來分析。跳到第二個方法。

注意看這個條件,if (elementdata == defaultcapacity_empty_elementdata),如果底層陣列為空,那麼就取,10和mincapacity中的較大者。什麼時候底層陣列回事空值呢?當初始化arraylist的時候使用無參構造,那麼在新增少於10個元素的時候,就會直接將底層陣列的長度設定成預設10。

ArrayList原始碼分析

arraylist是平時使用很多的乙個類,趁有時間,我也閱讀以下原始碼,以幫助自己加深理解。類的層次結構這裡就不列出了,主要分析一下原始碼部分,屬性部分 protected transient int modcount 0 這個屬性是從abstractlist繼承過來的,每次arraylist進行結...

ArrayList原始碼剖析

建構函式 有3個建構函式 1 在jdk原始碼中arraylist無參的建構函式,預設初始化大小是10 2 帶有指定大小引數的建構函式 3 帶有集合引數的建構函式 一 確定arrarlist的容量 1 若arraylist的容量不足以容納當前的全部元素,設定新的容量 原始容量 3 2 1。2 如果擴容...

ArrayList原始碼理解

與linkedlist原始碼理解放在一起查閱,效果更好 對隊成員變數的分析,可以知道arraylist的資料結構 對add 方法的分析,可以得知arraylist新增資料的效率不高 對get 方法的分析,可以看出arraylist查詢的效率非常高 對remove 方法的分析,可以了解到arrayli...