Java的List集合框架之ArrayList詳解
(一)List子父層級(jí)
- List接口繼承于Collection,Collection繼承Iterable;
- LIst接口實(shí)現(xiàn)類分為:Vector、ArrayList、LinkedLIst;
(二)List實(shí)現(xiàn)類
1、ArrayList實(shí)現(xiàn)類
(1)ArrayList底層是Object數(shù)組,transient Object[] elementData;
(2)ArrayList默認(rèn)容量為10或者構(gòu)造方法指定初始容量,private static final int DEFAULT_CAPACITY = 10;
(3)ArrayList擴(kuò)容是基于當(dāng)前容量的1.5倍,int newCapacity = oldCapacity + (oldCapacity >> 1);
(4)ArrayList是線程不安全的,在多線程環(huán)境下,會(huì)報(bào)并發(fā)修改異常java.util.ConcurrentModificationException。
2、常見源碼
(1)構(gòu)造方法:
//無參構(gòu)造方法,未指定初始容量 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//將空數(shù)組對(duì)象賦值給存儲(chǔ)數(shù)組 } //有參構(gòu)造方法,指定初始容量進(jìn)行初始化 public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity];//以傳入值對(duì)存儲(chǔ)數(shù)組進(jìn)行初始化 } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA;//賦值空數(shù)組初始化存儲(chǔ)數(shù)組 } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
(2)add方法:
//此處列舉常用add(返回值為boolean),其它指定位置插入add(返回空)方法暫不列舉,邏輯基本類似 public boolean add(E e) { ensureCapacityInternal(size + 1);//判斷是否需要擴(kuò)容 elementData[size++] = e;//將值存儲(chǔ)在數(shù)組上 return true; } //判斷是否需要擴(kuò)容,如需要?jiǎng)t進(jìn)行1.5倍擴(kuò)容 private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } //判定并計(jì)算容量大小值(舊的size+新的1) private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//判斷是否已被初始化 return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity;//返回實(shí)際已存值大?。╯ize)+將要存儲(chǔ)值大?。?) } //擴(kuò)容判定 private void ensureExplicitCapacity(int minCapacity) { modCount++;//操作次數(shù) if (minCapacity - elementData.length > 0)//判定當(dāng)前數(shù)組是否還能存入值 grow(minCapacity);//擴(kuò)容 } //數(shù)組最大值 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; private void grow(int minCapacity) { int oldCapacity = elementData.length;//當(dāng)前數(shù)組長度 int newCapacity = oldCapacity + (oldCapacity >> 1);//擴(kuò)容新數(shù)組大小(利用位運(yùn)算進(jìn)行1.5倍擴(kuò)大) if (newCapacity - minCapacity < 0)//判定擴(kuò)容后大小是否仍然不滿足存儲(chǔ)要求 newCapacity = minCapacity;//不滿足要求的前提下,直接將滿足值設(shè)置為擴(kuò)容后的數(shù)值 if (newCapacity - MAX_ARRAY_SIZE > 0)//判定是否超過數(shù)組最大值 newCapacity = hugeCapacity(minCapacity);//擴(kuò)容值超大設(shè)置 elementData = Arrays.copyOf(elementData, newCapacity);//數(shù)組數(shù)據(jù)遷移復(fù)制 } //判定擴(kuò)容后的容量是否是超大值 private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) //越界值判定 throw new OutOfMemoryError(); //返回?cái)U(kuò)大值,既可能是Integer最大值也可能是數(shù)組最大值 return (minCapacity > MAX_ARRAY_SIZE)?Integer.MAX_VALUE:MAX_ARRAY_SIZE; }
(3)get方法:
public E get(int index) { rangeCheck(index);//越界檢查 return elementData(index); } //越界檢查方法 private void rangeCheck(int index) { if (index >= size)//越界檢查 throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } //獲取索引數(shù)據(jù) E elementData(int index) { return (E) elementData[index];//直接將對(duì)應(yīng)索引數(shù)據(jù)返回 }
(4)set方法:
public E set(int index, E element) { rangeCheck(index);//檢查是否越界,不列舉,上述(3)中已列舉 E oldValue = elementData(index);//獲取指定索引已存在的值 elementData[index] = element;//將新值設(shè)置到指定索引位置 return oldValue;//返回舊值 }
(5)remove方法:
//暫只列舉根據(jù)索引刪除數(shù)組值,不列舉其他參數(shù)刪除(原理大體相同) public E remove(int index) { rangeCheck(index);//數(shù)組越界檢查 modCount++;//操作次數(shù) E oldValue = elementData(index);//獲取指定索引數(shù)組值 int numMoved = size - index - 1;//需要移動(dòng)的數(shù)組長度 if (numMoved > 0)//判定因?yàn)閯h除指定索引值后是否需要移動(dòng)后面的數(shù)組值 System.arraycopy(elementData, index+1, elementData, index, numMoved);//系統(tǒng)復(fù)制數(shù)組 elementData[--size] = null; //將因刪除而導(dǎo)致的空位置空,便于GC return oldValue;//將刪除的值返回 }
3、總結(jié)
(1)ArrayList線程不安全,并發(fā)操作ArraylList會(huì)報(bào)并發(fā)修改異常java.util.ConcurrentModificationException。
(2)ArrayList默認(rèn)容量為10(構(gòu)造方法未指定初始容量為0),擴(kuò)容是利用位運(yùn)算(右移一位)和直接相加進(jìn)行1.5倍擴(kuò)容。
到此這篇關(guān)于Java的List集合框架之ArrayList詳解的文章就介紹到這了,更多相關(guān)List集合框架之ArrayList內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring security實(shí)現(xiàn)記住我下次自動(dòng)登錄功能過程詳解
這篇文章主要介紹了Spring security實(shí)現(xiàn)記住我下次自動(dòng)登錄功能過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03Java反射之通過反射獲取一個(gè)對(duì)象的方法信息(實(shí)例代碼)
下面小編就為大家?guī)硪黄狫ava反射之通過反射獲取一個(gè)對(duì)象的方法信息(實(shí)例代碼)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-10-10Mac配置 maven以及環(huán)境變量設(shè)置方式
這篇文章主要介紹了Mac配置 maven以及環(huán)境變量設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08Java集合之Comparable和Comparator接口詳解
Java提供了Comparable接口與Comparator接口,它們?yōu)閿?shù)組或集合中的元素提供了排序邏輯,實(shí)現(xiàn)此接口的對(duì)象數(shù)組或集合可以通過Arrays.sort或Collections.sort進(jìn)行自動(dòng)排序。本文將通過示例講講它們的使用,需要的可以參考一下2022-12-12Springboot jar包 idea 遠(yuǎn)程調(diào)試的操作過程
文章介紹了如何在IntelliJ IDEA中遠(yuǎn)程調(diào)試Spring Boot項(xiàng)目的Jar包,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-11-11IntelliJ IDEA 刷題利器 LeetCode 插件詳解
這篇文章主要介紹了IntelliJ IDEA 刷題利器 LeetCode 插件,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08Mybatis中動(dòng)態(tài)SQL,if,where,foreach的使用教程詳解
MyBatis的動(dòng)態(tài)SQL是基于OGNL表達(dá)式的,它可以幫助我們方便的在SQL語句中實(shí)現(xiàn)某些邏輯。這篇文章主要介紹了Mybatis中動(dòng)態(tài)SQL,if,where,foreach的使用教程,需要的朋友可以參考下2017-11-11