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