集合 02 ArrayList原理深入解析

2021-10-08 06:03:13 字數 2562 閱讀 5692

arraylist就是陣列列表,主要用來裝載資料,當我們裝載的是基本型別的資料int,long,boolean,short,byte…的時候我們只能儲存他們對應的包裝類,它的主要底層實現是陣列object elementdata。

和linkedlist相比

linkedlist的底層是鍊錶,所以擁有鍊錶的特點,查詢速度較陣列慢,增刪要快,而arraylist的底層是陣列實現的,增刪慢,查詢和訪問元素的速度較快。

arraylist的特點

增刪慢,查詢快,執行緒不安全,使用頻率很高

arraylist初始化時,初始容量為0,只有真正對資料進行新增add時,才分配預設default_capacity = 10的初始容量。

分析

4個成員變數,下面的成員變數分別是預設容量、空物件陣列、預設物件陣列

從注釋可以看出,elementdata是乙個物件陣列快取

分析

可以看出,對於arraylist,如果在new物件的時候傳引數,也就是設定預設容量

如果預設容量大於0,elementdata會指向乙個容量為預設容量的物件陣列

如果預設容量等於0,那麼elementdata會指向乙個空物件陣列的位址

如果預設容量小於0,因為容量不能為負,就會拋異常

分析

可以看出,對於arraylist,如果在new物件的時候不傳引數,也就是不設定預設容量,那麼elementdata會指向乙個預設空物件陣列的位址

陣列的長度是有限制的,那麼如果add元素超過了arraylist容量會怎樣呢?

下面是add方法的原始碼

arraylist的增加元素時首先會呼叫方法 ensurecapacityinternal,去判斷arraylist的預設容量是否足夠,如果不夠就會擴容

我們先看看ensurecapacityinternal方法,引數mincapacity的值此時是傳進來的size+1(size是int型別,初值為0)

繼續點,看ensureexplicitcapacity方法

modcount用來記錄修改次數,然後判斷期望最小容量減去快取陣列的長度是否大於0

如果大於0,就呼叫grow方法,進行擴容

其實很好理解,因為第一次新增元素是,mincapacity的值是size+1也就是1,第二次新增元素是2,也就是說mincapacity是存入元素的容量,所以也被稱為期望最小容量,如果快取陣列的容量比期望的最小容量都要小,那麼肯定放不下新增的元素,那麼就必須呼叫grow方法進行擴容了。

陣列的長度是有限制的,那麼如果add元素超過了arraylist容量會怎樣呢?

在擴容的時候,老版本的jdk和8以後的版本是有區別的,8之後的效率更高了,採用了位運算,右移一位,其實就是除以2這個操作。

從上文可知,mincapacity就是arraylist新增元素之前的元素個數+1之後的期望最小容量(因為add每次只能新增乙個元素,所以arraylist的現在容量必須大於mincapacity,如果不大於就會擴容)

grow方法中,首先獲取了擴容前的容量oldcapacity

新的容量為舊容量的1.5倍(舊容量加舊容量右移一位)

從這可以得出,arraylist每次擴容都是原來的1.5倍,然後判斷

如果新的容量減去期望最小容量小於0則新的容量就是最小期望容量

如果新的容量減去arraylist的最大值也就是max_array_size的話

看hugecapacity方法

max_array_size如下

integer.max_value如下

Java集合 ArrayList 實現原理

1.arraylist概述 arraylist是list介面的可變陣列的實現。實現了所有可選列表操作,並允許包括 null 在內的所有元素。除了實現 list 介面外,此類還提供一些方法來操作內部用來儲存列表的陣列的大小。每個arraylist例項都有乙個容量,該容量是指用來儲存列表元素的陣列的大小...

集合框架 ArrayList的實現原理

arraylist是基於陣列實現的,並且可以動態擴容。下面簡述一下arraylist的特性 1 get和set操作效能很高,可以按索引獲取 2 在末尾add和remove的效率也很高,不需要移動元素 3 常規的add和remove效能不佳,視具體情況而定。4 動態擴容,和陣列相比最大的優勢。在對ar...

06ArrayList集合各種方法(02)

using system using system.collections.generic using system.linq using system.text using system.threading.tasks using system.collections namespace arra...