1. 程式人生 > >ArrayList的原始碼分析(一)

ArrayList的原始碼分析(一)

我想大家既然能看到這篇文章我就不用解釋Arraylist是啥了,簡單點說就是一個動態物件陣列,然後就這個集合的原始碼拿出來給大家分析一下我的個人看法和收穫,例項程式碼是jdk1.8的原始碼

首先可以看到,Arraylist這個類繼承了AbstractList這個類,實現了list這個介面等等

然後我們來看看它的一些屬性: 

從這裡可以看到arraylist的預設長度為10,也就是說明當你建立一個arraylist的時候它預設的長度為10

這就是arraylist集合的本體,在這裡證明了ArrayList的底層就是物件陣列,並且預設是個空的

這是arraylist的長度屬性,它的size()方法就是直接返回這個size,這個長度指的是集合的長度,而不是底層物件陣列的容量

Arraylist的長度也不是無限的,最大長度為Integer的最大長度-8

接下來咱們來看看它的構造方法,:

首先是無參的構造方法,在這裡可以看的明天建立了一個長度為10的物件陣列,在方法體中的變數在上方都有介紹

第一個有參的構造方法,在這裡可以看的出構造方法中的引數就是你建立物件陣列的長度,當你使用這個構造方法的時候你就能指定你建立集合的長度,某些情況下這樣能優化集合的效能,具體大家可以去看看我的這篇文章:https://blog.csdn.net/qq_41594146/article/details/81870931   如果引數為0的話則依然使用預設的長度10,負數則出現異常

接下來看看第二個有參的構造方法,這裡的引數認為只能放Collection的子類,關於泛型大家可以去看我的這篇文章:https://blog.csdn.net/qq_41594146/article/details/82181102    首先將引數集合轉成陣列用物件陣列接收,分兩種情況,如果引數集合的長度不是0的話,則繼續判斷這個陣列的型別是不是物件陣列,如果不是則複製成一個物件陣列,如果該集合的長度為0,那麼生成一個為空的arraylist

咱們再來看看我們常用的方法的一些原始碼,看看到底arraylist怎麼樣實現動態陣列

首先是add方法

這個是我們常用的add方法,直接放一個物件新增到集合中去,然後我一步步跟蹤看看它是怎麼樣新增的

,首先是執行了一個ensureCapacityInternal方法,而它的引數就是當前陣列長度加一   elementData是當前集合陣列的一個緩衝陣列

接下來看看calculateCapacity方法, 如果緩衝陣列就是集合本體陣列的話,則返回兩個引數中較大的一個,引數一為預設長度10

但是如果不是的話就返回當前集合的size+1   

在看看ensureExplicitCapacity方法,這個方法翻譯為確保明確的容量,看名字大概也能猜出一點是幹啥的.這個判斷是如果當前集合長度+1的數減去緩衝陣列的長度>0的話執行grow方法,引數為當前集合長度+1,也就是mincapacity

這就是grow方法,  首先用一個int oldCapacity接收,緩衝陣列的長度,也就是舊陣列的長度,再定義一個新陣列的長度newCapacity,這個變數的長度為舊陣列的長度加上舊陣列的一半的長度,關於這個符號>>大家可以去看我的這篇文章:https://blog.csdn.net/qq_41594146/article/details/81449984   這就是為什麼別人說arraylist的擴容機制是1.5倍的所在,後面這兩個判斷是判斷有沒有超過容量或者是新陣列的長度過小,最後就是一個copy陣列的過程,引數1為舊陣列,引數2為新陣列的長度,  然後用緩衝陣列來接收,關於這個緩衝陣列的官方介紹:

儲存ArrayList元素的陣列緩衝區。   ArrayList的容量是此陣列緩衝區的長度。新增第一個元素時,任何帶有elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA  的空ArrayList都將擴充套件為DEFAULT_CAPACITY   

也就是說在改變arraylist的陣列之後緩衝陣列就是集合的底層陣列

如果對你有幫助的話可以點下贊,謝謝,後序也將會有更多關於java集合的底層原始碼分析