详解java集合之ArrayList——底层实现是一个Object数组。分析ArrayList的自动扩容,原来不一定是1.5倍
ArrayList的底層實現——非private權限的Object數組
ArrayList的類結構圖
?
1. ArrayList的創建
1.1 參數為空的構造方法——ArrayList內部的Object數組使用默認的空數組,被初始化為{}
?
1.2 初始容量作為參數的構造方法——會直接創建相應大小的Object數組
?
1.3 Collection對象作為參數的構造方法
?
2. ArrayList添加元素時的動態擴容機制
2.1?初始容量為0或者使用參數為空的構造方法創建的ArrayList對象自動擴容
2.1.1 源碼分析:追蹤add方法,最終追蹤到grow方法。
2.1.2 初始容量為0或者使用參數為空的構造方法得到的內部Object數組(elementData屬性)為{},也就是elemenntData.length=0,并且size=0。DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {},DEFAULT_CAPACITY = 10,源碼如下。
2.1.3 grow方法分析
?
2.2 后期添加元素的自動擴容分析
2.2.1 需要注意的是,每次ArrayList數組滿了(size == elementData.length)才會擴容。其次,因為每次擴容有兩個值可取,如果是取原始容量的一半進行擴容,那么擴容倍數是1.5倍,不然ArrayList擴容倍數不一定。
?
3. ArrayList移除元素
3.1 不管是按索引移除還是直接移除對象,最終都是通過fastRemove方法按索引移除對象,源碼追蹤如下。
3.2?需要注意的是,直接移除對象時,查找對象使用的是equals方法。
3.3 fastRemove方法最終底層使用數組移動的arraycopy方式移除元素,源碼如下。
?
4. ArrayList查找某個元素
4.1 indexOf方法查找元素并返回索引下標,內部通過遍歷數組查找元素。所以常說數組查詢快,鏈表查詢慢,查詢是指定位。如果是查找的話,數組和鏈表一樣都得遍歷。
?
5. ArrayList獲取某個索引或更改某個索引的元素
5.1 獲取某個索引元素,直接通過下標取出數組元素
5.2 更改某個索引的元素,直接通過下標更改數組元素
?
6. ArrayList的其它方法
6.1 ArrayList內沒有toString方法,使用了間接父類AbstractCollection的toString方法,遍歷每個元素并調用各自的toString方法,最終使用StringBuffer拼接。
6.2 ArrayList使用clear()方法清空數據,內部是將各個元素指向null。
6.3 ArrayList的size方法得到當前元素個數,而不是內部elementData數組長度。
6.4 ArrayList的toArray方法得到的數組是Object類型,需要自己強轉。
?
?
總結
以上是生活随笔為你收集整理的详解java集合之ArrayList——底层实现是一个Object数组。分析ArrayList的自动扩容,原来不一定是1.5倍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Future和CompletableFu
- 下一篇: Integer及String的equal