ArrayList底層操作機(jī)制源碼解析
ArrayList 的底層操作機(jī)制源碼
擴(kuò)容機(jī)制:
- ArrayList中維護(hù)了一個(gè)0bject類型的數(shù)組elementData. transient Object[] elementData; //transient表示瞬間,短暫的,表示該屬性不會(huì)被序列化
- 當(dāng)創(chuàng)建ArrayList對(duì)象時(shí),如果使用的是無(wú)參構(gòu)造器,則初始elementData容量為0,第1次添加,則擴(kuò)容elementData為10,如需要再次擴(kuò)容,則擴(kuò)容elementData為1.5倍。
- 如果使用的是指定大小的構(gòu)造器,則初始elementData容量為指定大小,如果需要擴(kuò)容, 則直接擴(kuò)容elementData為1.5倍。
debug源碼
- 使用無(wú)參構(gòu)造器,創(chuàng)建和使用ArrayList源碼
/** * 創(chuàng)建一個(gè)空的elementData數(shù)組 = {} */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
/** * 執(zhí)行l(wèi)ist.add方法, 先確定是否要擴(kuò)容,再執(zhí)行添加操作 */ public boolean add(E e) { // 每次都要看看是否需要擴(kuò)容 ensureCapacityInternal(size + 1); //ensureCapacityInternal:確認(rèn)容量 elementData[size++] = e; return true; }
/** * 該方法確定minCapacity , 第一次擴(kuò)容為10 */ private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); }
/** * modCount:記錄當(dāng)前集合被修改的次數(shù),如果elementData的容量不夠,就調(diào)用grow方法擴(kuò)容 */ private void ensureExplicitCapacity(int minCapacity) { modCount++; // modCount:記錄當(dāng)前集合被修改的次數(shù),防止多線程操作出現(xiàn)的異常 if (minCapacity - elementData.length > 0) // 如果elementData的容量不夠,就調(diào)用grow方法擴(kuò)容 grow(minCapacity); }
/** * 真的擴(kuò)容,使用擴(kuò)容機(jī)制來(lái)確定擴(kuò)容到多大 * 第一次newCapacity為10, 第二次及其以后按照1.5倍擴(kuò)容 * 擴(kuò)容的是Arrays.copyOf(), 能保留以前的數(shù)據(jù) */ private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; //(oldCapacity >> 1)的意思是oldCapacity / 2 int newCapacity = oldCapacity + (oldCapacity >> 1); //(1.5倍擴(kuò)容) if (newCapacity - minCapacity < 0) newCapacity = minCapacity; //第一次就是10 if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // Arrays.copyOf 將 elementData{} 擴(kuò)容為newCapacity大小 elementData = Arrays.copyOf(elementData, newCapacity); }
方法一步步返回
- 使用有參構(gòu)造器,創(chuàng)建和使用ArrayList源碼
/** * 第一次就按照elementData的1.5倍擴(kuò)容 * 整個(gè)執(zhí)行的流程和前面的無(wú)參構(gòu)造的一樣 */ public ArrayList(int initialCapacity) { if (initialCapacity > 0) { // 創(chuàng)建了一個(gè)指定大小的elementData數(shù)組 this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
整個(gè)執(zhí)行的流程和無(wú)參構(gòu)造的一樣
到此這篇關(guān)于ArrayList底層操作機(jī)制源碼解析的文章就介紹到這了,更多相關(guān)ArrayList源碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Jmeter參數(shù)化實(shí)現(xiàn)原理及過(guò)程解析
這篇文章主要介紹了Jmeter參數(shù)化實(shí)現(xiàn)原理及過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07Java實(shí)現(xiàn)數(shù)字轉(zhuǎn)成英文的方法
這篇文章主要介紹了Java實(shí)現(xiàn)數(shù)字轉(zhuǎn)成英文的方法,涉及java數(shù)組與字符串的相關(guān)操作技巧,需要的朋友可以參考下2015-05-05JDBC的基本操作與Statement和PreparedStateMent使用區(qū)別分析
這篇文章主要介紹了JDBC的基本操作與Statement和PreparedStateMent使用區(qū)別,Java Database Connectivity,它是代表一組獨(dú)立于任何數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)的API,聲明在java.sql與javax.sql包中,是SUN(現(xiàn)在Oracle)提供的一組接口規(guī)范2023-04-04Java如何設(shè)置過(guò)期時(shí)間的map的幾種方法
本文主要介紹了Java如何設(shè)置過(guò)期時(shí)間的map的幾種方法,常見(jiàn)的解決方法有:ExpiringMap、LoadingCache及基于HashMap的封裝三種,下面就詳細(xì)的介紹一下,感興趣的可以了解下2022-03-03Spring Boot中使用AOP統(tǒng)一處理web層異常的方法
這篇文章主要介紹了Spring Boot中使用AOP統(tǒng)一處理web層異常的相關(guān)資料,需要的朋友可以參考下2018-03-03springboot 配置DRUID數(shù)據(jù)源的方法實(shí)例分析
這篇文章主要介紹了springboot 配置DRUID數(shù)據(jù)源的方法,結(jié)合實(shí)例形式分析了springboot 配置阿里DRUID數(shù)據(jù)源的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2019-12-12springboot+mybatis配置clickhouse實(shí)現(xiàn)插入查詢功能
這篇文章主要介紹了springboot+mybatis配置clickhouse實(shí)現(xiàn)插入查詢功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08Java Spring @Autowired的這些騷操作,你都知道嗎
這篇文章主要介紹了徹底搞明白Spring中的自動(dòng)裝配和Autowired注解的使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2021-09-09詳解Java synchronized關(guān)鍵字的用法
在多線程編程中常常使用鎖機(jī)制來(lái)確保同一時(shí)刻只有一個(gè)線程能夠修改共享內(nèi)存,在Java中一般是使用synchronized作為鎖機(jī)制,下面就讓我們來(lái)學(xué)習(xí)一下如何使用synchronized實(shí)現(xiàn)線程安全吧2023-08-08