Java的List集合框架之ArrayList詳解
(一)List子父層級

- 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)境下,會報(bào)并發(fā)修改異常java.util.ConcurrentModificationException。
2、常見源碼
(1)構(gòu)造方法:
//無參構(gòu)造方法,未指定初始容量
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//將空數(shù)組對象賦值給存儲數(shù)組
}
//有參構(gòu)造方法,指定初始容量進(jìn)行初始化
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];//以傳入值對存儲數(shù)組進(jìn)行初始化
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;//賦值空數(shù)組初始化存儲數(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;//將值存儲在數(shù)組上
return true;
}
//判斷是否需要擴(kuò)容,如需要則進(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)+將要存儲值大?。?)
}
//擴(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ò)容后大小是否仍然不滿足存儲要求
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];//直接將對應(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;//需要移動的數(shù)組長度
if (numMoved > 0)//判定因?yàn)閯h除指定索引值后是否需要移動后面的數(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會報(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringDataRedis入門和序列化方式解決內(nèi)存占用問題小結(jié)
spring-data-redis是spring-data模塊的一部分,專門用來支持在spring管理項(xiàng)目對redis的操作,這篇文章主要介紹了SpringDataRedis入門和序列化方式解決內(nèi)存占用問題,需要的朋友可以參考下2022-12-12
SpringBoot JPA實(shí)現(xiàn)查詢多值
這篇文章主要為大家詳細(xì)介紹了SpringBoot JPA實(shí)現(xiàn)查詢多值,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-08-08
java自定義異常以及throw和throws關(guān)鍵字用法
這篇文章主要介紹了java自定義異常以及throw和throws關(guān)鍵字用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02
基于Spring + Spring MVC + Mybatis 高性能web構(gòu)建實(shí)例詳解
這篇文章主要介紹了基于Spring + Spring MVC + Mybatis 高性能web構(gòu)建實(shí)例詳解,需要的朋友可以參考下2017-04-04
詳解SpringSecurity中的Authentication信息與登錄流程
這篇文章主要介紹了SpringSecurity中的Authentication信息與登錄流程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09

