詳解Java List的擴(kuò)容機(jī)制原理及應(yīng)用
引言
在Java中,List是一種非常常用的數(shù)據(jù)結(jié)構(gòu),用于存儲(chǔ)有序的元素集合。List的底層實(shí)現(xiàn)有多種,如ArrayList、LinkedList等。在使用List時(shí),我們經(jīng)常會(huì)遇到一個(gè)問(wèn)題:當(dāng)元素?cái)?shù)量超過(guò)了List的初始容量時(shí),List會(huì)如何擴(kuò)容?本文將分析Java List的擴(kuò)容機(jī)制原理,并通過(guò)示例代碼和測(cè)試代碼來(lái)加強(qiáng)闡述內(nèi)容。
List的擴(kuò)容機(jī)制原理
在Java中,List的擴(kuò)容機(jī)制是為了在元素?cái)?shù)量變多時(shí),能夠保持List的性能穩(wěn)定。當(dāng)List需要擴(kuò)容時(shí),會(huì)創(chuàng)建一個(gè)更大的容量,并將舊的元素復(fù)制到新的容器中。下面我們將詳細(xì)解析ArrayList的擴(kuò)容機(jī)制。
ArrayList的擴(kuò)容策略
ArrayList是使用數(shù)組作為底層數(shù)據(jù)結(jié)構(gòu)來(lái)實(shí)現(xiàn)List的。當(dāng)ArrayList需要擴(kuò)容時(shí),會(huì)創(chuàng)建一個(gè)新的數(shù)組來(lái)存儲(chǔ)元素,并將舊數(shù)組中的元素復(fù)制到新數(shù)組中。ArrayList的擴(kuò)容策略如下:
- 首先,當(dāng)ArrayList的元素?cái)?shù)量超過(guò)了其數(shù)組的長(zhǎng)度時(shí),就會(huì)觸發(fā)擴(kuò)容操作。
- 擴(kuò)容時(shí),ArrayList會(huì)創(chuàng)建一個(gè)新的容量更大的數(shù)組,通常是原數(shù)組容量的1.5倍(可以通過(guò)修改源碼進(jìn)行調(diào)整)。
- 然后,ArrayList會(huì)將舊數(shù)組中的元素按順序復(fù)制到新的數(shù)組中。
- 最后,將新數(shù)組設(shè)置為ArrayList的底層數(shù)組,完成擴(kuò)容操作。
通過(guò)這種擴(kuò)容策略,ArrayList能夠在元素?cái)?shù)量變多時(shí),保持較好的性能。因?yàn)閿U(kuò)容操作的時(shí)間復(fù)雜度為O(n),其中n為元素?cái)?shù)量。
擴(kuò)容具體實(shí)現(xiàn)代碼
下面給出一個(gè)簡(jiǎn)單的示例代碼,展示了ArrayList的擴(kuò)容具體實(shí)現(xiàn):
public class ArrayList<E> implements List<E> { private static final int DEFAULT_CAPACITY = 10; private Object[] elementData; private int size; public ArrayList() { this.elementData = new Object[DEFAULT_CAPACITY]; this.size = 0; } public void add(E e) { ensureCapacity(size + 1); elementData[size++] = e; } private void ensureCapacity(int minCapacity) { if (minCapacity > elementData.length) { int newCapacity = elementData.length + (elementData.length >> 1); if (newCapacity < minCapacity) newCapacity = minCapacity; elementData = Arrays.copyOf(elementData, newCapacity); } } // 其他方法省略... }
在上述代碼中, ensureCapacity
方法負(fù)責(zé)擴(kuò)容操作。當(dāng)元素?cái)?shù)量超過(guò)了數(shù)組長(zhǎng)度時(shí),會(huì)觸發(fā)擴(kuò)容操作。 Arrays.copyOf
方法用于創(chuàng)建新的數(shù)組并將舊數(shù)組中的元素復(fù)制進(jìn)去。
示例代碼和測(cè)試代碼
為了更好地理解和驗(yàn)證ArrayList的擴(kuò)容機(jī)制,下面給出了示例代碼和測(cè)試代碼:
import java.util.ArrayList; public class ArrayListResizeDemo { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(5); // 添加6個(gè)元素,觸發(fā)擴(kuò)容 for (int i = 1; i <= 6; i++) { list.add(i); } System.out.println("List size: " + list.size()); // 輸出:6 System.out.println("List capacity: " + getArrayListCapacity(list)); // 輸出:10 } // 獲取ArrayList的容量 private static int getArrayListCapacity(ArrayList<?> list) { try { java.lang.reflect.Field capacityField = ArrayList.class.getDeclaredField("elementData"); capacityField.setAccessible(true); return ((Object[]) capacityField.get(list)).length; } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); return -1; } } }
上述示例代碼創(chuàng)建了一個(gè)初始容量為5的ArrayList,然后添加了6個(gè)元素。在添加第6個(gè)元素時(shí),會(huì)觸發(fā)擴(kuò)容操作。通過(guò) getArrayListCapacity
方法獲取ArrayList的容量,驗(yàn)證了擴(kuò)容操作已經(jīng)生效。
結(jié)論
本文詳細(xì)介紹了Java List的擴(kuò)容機(jī)制原理,并通過(guò)示例代碼和測(cè)試代碼加強(qiáng)了闡述內(nèi)容。ArrayList作為常用的List實(shí)現(xiàn)類,其擴(kuò)容機(jī)制可以保持較好的性能。通過(guò)了解和理解Java中List的擴(kuò)容機(jī)制,我們能夠更好地在實(shí)際開發(fā)中合理使用List。
到此這篇關(guān)于詳解Java List的擴(kuò)容機(jī)制原理及應(yīng)用的文章就介紹到這了,更多相關(guān)Java List的擴(kuò)容機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
辨析Java中的String與StringBuffer及StringBuilder字符串類
這里將為大家來(lái)辨析Java中的String與StringBuffer及StringBuilder字符串類型,通常來(lái)說(shuō)StringBuilder的性能更加,需要的朋友可以參考下2016-05-05MySQL如何設(shè)置自動(dòng)增長(zhǎng)序列SEQUENCE的方法
本文主要介紹了MySQL如何設(shè)置自動(dòng)增長(zhǎng)序列SEQUENCE的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12httpclient staleConnectionCheckEnabled獲取連接流程解析
這篇文章主要為大家介紹了httpclient staleConnectionCheckEnabled獲取連接流程示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11String.intern()作用與常量池關(guān)系示例解析
這篇文章主要為大家介紹了String.intern()作用與常量池關(guān)系示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08如何開啟控制臺(tái)輸出mybatis執(zhí)行的sql日志問(wèn)題
這篇文章主要介紹了如何開啟控制臺(tái)輸出mybatis執(zhí)行的sql日志問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09SpringBoot實(shí)現(xiàn)單點(diǎn)登錄(SSO)的四種方案
單點(diǎn)登錄(Single?Sign-On,SSO)是企業(yè)應(yīng)用系統(tǒng)中常見(jiàn)的用戶認(rèn)證方案,它允許用戶使用一組憑證訪問(wèn)多個(gè)相關(guān)但獨(dú)立的系統(tǒng),無(wú)需重復(fù)登錄,本文給大家介紹了SpringBoot實(shí)現(xiàn)單點(diǎn)登錄(SSO)的四種方案,需要的朋友可以參考下2025-04-04Component-Scan 不掃描jar里面的類問(wèn)題
這篇文章主要介紹了Component-Scan 不掃描jar里面的類問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11Java內(nèi)部類原理與用法實(shí)例總結(jié)
這篇文章主要介紹了Java內(nèi)部類原理與用法,結(jié)合實(shí)例形式總結(jié)分析了非靜態(tài)內(nèi)部類、靜態(tài)內(nèi)部類、局部類等相關(guān)概念、原理、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2018-08-08