ArryaList原始碼淺析
一 .繼承關系

? ArrayList是java中常用的集合框架之一,其內部資料存盤為陣列形式,其繼承關系如上圖所示,
二.屬性與方法
屬性
-
private static final long serialVersionUID = 8683452581122892189L;序列化版本ID,用于反序列化進行版本比較,若反序列化時UID不一致將會拋出java.io.InvalidClassException例外,
-
private static final Object[] EMPTY_ELEMENTDATA = https://www.cnblogs.com/classicmoon/archive/2021/04/25/{};用于空串列的共享空物件陣列,避免每次實體化時重新申請,
-
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = https://www.cnblogs.com/classicmoon/archive/2021/04/25/{};同樣也是用于空串列的共享空物件陣列,用于無參構造,和EMPTY_ELEMENTDATA的具體區別見注意事項,
-
transient Object[] elementData;用于存放該串列的資料,
-
private int size;該串列中元素的個數(指的是元素的個數,而非elementData陣列的大小),
-
private static final int DEFAULT_CAPACITY = 10;默認的初始化陣列大小,
-
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;陣列申請的最大大小,為什么會是Integer.MAX_VALUE - 8?這是因為有些虛擬機會在陣列頭部占用一定的空間,如果嘗試申請Integer.MAX_VALUE大小的陣列,可能會導致OutOfMemoryError: Requested array size exceeds VM limit,
方法
構造方法
-
public ArrayList(int initialCapacity);有參構造方法,創建一個指定陣列大小的空串列,如果initialCapacity為0,其elementData=https://www.cnblogs.com/classicmoon/archive/2021/04/25/EMPTY_ELEMENTDATA,
-
public ArrayList();無參構造方法,elementData=https://www.cnblogs.com/classicmoon/archive/2021/04/25/DEFAULTCAPACITY_EMPTY_ELEMENTDATA,
-
public ArrayList(Collection<? extends E> c);有參構造方法,將傳入的集合轉換為陣列存入elementData中,若集合為空,elementData=https://www.cnblogs.com/classicmoon/archive/2021/04/25/EMPTY_ELEMENTDATA,
串列核心方法
-
public void ensureCapacity(int minCapacity);ArryaList的擴容方法,將物件陣列的大小擴容為至少滿足minCapacity大小的程度,
擴容規則:
- 計算minExpand,若elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA時為0,否則為DEFAULT_CAPACITY = 10,
- 若minCapacity <= minExpand時,不進行擴容,否則繼續進行擴容
- 計算minCapacity是否大于當前陣列大小,大于時才進行擴容,防止資料丟失,
- 計算newCapacity(原陣列大小的1.5倍)
- newCapacity取newCapacity與minCapacity的較大者
- 判斷newCapacity是否大于MAX_ARRAY_SIZE,大于時若minCapacity < 0 拋出OutOfMemoryError例外,minCapacity > MAX_ARRAY_SIZE時newCapacity取Integer.MAX_VALUE,否則取MAX_ARRAY_SIZE,
- 根據newCapacity創建新陣列,并將原陣列資料進行拷貝,
-
public int size();回傳size的值,即串列中元素的個數,
-
public boolean isEmpty();判斷串列是否為空,即size == 0?
-
public boolean contains(Object o);查詢串列中是否包含物件o,若不包含物件o,回傳false,
注意:這里的o可以為null,此時比較直接使用==比較符,若o為物件,則呼叫該物件的equals方法,(內部實作為indexOf(Object o)),
-
public int indexOf(Object o);從頭開始查詢串列,回傳物件o的陣列下表,未查詢到時回傳-1,
注意:這里的o可以為null,此時比較直接使用==比較符,若o為物件,則呼叫該物件的equals方法,
-
public int lastIndexOf(Object o);從末尾開始查詢串列,回傳物件o的陣列下表,未查詢到時回傳-1,
注意:這里的o可以為null,此時比較直接使用==比較符,若o為物件,則呼叫該物件的equals方法,
-
public E get(int index);根據索引值獲取指定位置的資料,
-
public E set(int index, E element);根據索引值重新設定指定位置的資料,回傳舊值,
-
public boolean add(E e);判斷陣列是否能容納size+1個元素,不滿足則先進行擴容,最后添加元素至陣列末尾,
-
public void add(int index, E element);判斷陣列是否能容納size+1個元素,不滿足則先進行擴容,最后添加元素至指定的索引位置,
-
public E remove(int index);洗掉指定索引位置的資料,回傳洗掉元素的值,
-
public boolean remove(Object o);洗掉指定的元素,o可以為null,從陣列頭部開始配置,洗掉匹配到的第一個元素,
-
public void clear();將陣列所有元素置為null,size=0,
-
public boolean addAll(Collection<? extends E> c);
功能方法
-
public void trimToSize();調整物件陣列elementData的大小與size的值一致,若size==0時將elementData的參考指向EMPTY_ELEMENTDATA,該方法主要用于減少串列的大小,釋放存盤空間,
-
public Object clone();Object.clone()方法的實作,淺拷貝,
-
public Object[] toArray();回傳該串列元素的一個新陣列,注意同樣是淺拷貝,
-
public <T> T[] toArray(T[] a);將串列中元素復制到陣列a中,
注意:當a.length<list.size時,原陣列不會有任何變化,a.length=list.size時,原陣列元素和串列中元素一致,a.length>list.size, a[0]~a[size-1]為串列中元素,a[size]置為null,
-
public boolean addAll(Collection<? extends E> c);將指定集合添加至陣列末尾,
-
public boolean addAll(int index, Collection<? extends E> c);將指定集合添加至指定索引處,
-
public boolean removeAll(Collection<?> c);將既存在原串列中又存在集合c中的元素移除出串列,即兩集合的差集,
-
public boolean retainAll(Collection<?> c);將既存在原串列中又存在集合c中的元素保留,即兩集合的交集,
-
public List<E> subList(int fromIndex, int toIndex);根據指定的索引回傳一個新的串列,
注意:該串列不是ArryaList,而是ArrayList的一個內部類SubList!
迭代器相關方法
-
public ListIterator<E> listIterator(int index);從指定索引處回傳迭代器ListItr
-
public ListIterator<E> listIterator();從陣列起始處回傳迭代器ListItr
-
public Iterator<E> iterator();回傳迭代器Itr
三.注意事項
-
EMPTY_ELEMENTDATA與DEFAULTCAPACITY_EMPTY_ELEMENTDATA
ArryaList的無參建構式會默認elementData為DEFAULTCAPACITY_EMPTY_ELEMENTDATA,在擴容時若需求大小小于DEFAULT_CAPACITY(10)時,擴容為10,防止在串列小的時候頻繁擴容,
-
ArrayList支持序列化為什么elementData被transient修飾?
在writeObject和readObject方法中進行了處理,只序列化實際存盤的元素和size,而不是整個elementData陣列,因為elementData陣列的大小比size大,不需要序列化大于size的這部分陣列,
-
迭代器ListItr和Itr的區別
ListItr繼承自Itr,Itr只能向后迭代,而ListItr不僅可以向后迭代,同時也可以向前迭代,
-
ArrayList的執行緒安全性
ArrayList是非執行緒安全的,若需要保證執行緒安全,使用List list = Collections.synchronizedList(new ArrayList(...));即可,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/280163.html
標籤:其他
上一篇:pandas(9):排序
