private static final long serialVersionUID = 8683452581122892189L;//惟一序列號ID
private static final int DEFAULT_CAPACITY = 10;//jdk7以前初始容量爲10,相似餓漢式,jdk8之後初始容量爲0,相似懶漢式
private static final Object[] EMPTY_ELEMENTDATA = {};//有參構造且傳入大小爲0時的空數組
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//無參構造的空數組
transient Object[] elementData; //實際存儲元素的數組
private int size;//實際存儲的元素個數
//構造函數
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {//懶漢式
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {//餓漢式
this.elementData = EMPTY_ELEMENTDATA;
} else {//傳入的初始容量小於0,非法,拋出異常
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public ArrayList(Collection<? extends E> c) {
//傳入一個集合,首先轉換爲Object數組。數組長度不爲0時,若是傳入的集合時ArrayList,那麼直接賦值底層數組,不然複製底層數組。若是長度爲0,那麼相似有參構造方法參數爲0的狀況。
Object[] a = c.toArray();
if ((size = a.length) != 0) {
if (c.getClass() == ArrayList.class) {
elementData = a;
} else {
elementData = Arrays.copyOf(a, size, Object[].class);
}
} else {
// replace with empty array.
elementData = EMPTY_ELEMENTDATA;
}
}
public void trimToSize() {
//modCount是父抽象類AbstractList中的一個持久化變量,記錄了ArrayList結構變化的次數。
modCount++;
//若是當前元素個數小於元素數組的長度時,元素數組會根據元素個數是否爲0被修改位空數組或者當前數組size的copy。
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
public void ensureCapacity(int minCapacity) {
//若是要求的最小容量大於當前元素數組的長度,且元素數組非空或者要求的最小容量大於初始容量,那麼就進行結構修改,使用增加,增加到最小容量。
if (minCapacity > elementData.length
&& !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
&& minCapacity <= DEFAULT_CAPACITY)) {
modCount++;
grow(minCapacity);
}
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;//最大元素數組容量爲2^31-9。
private Object[] grow(int minCapacity) {
//增加的有參方法,將元素數組複製爲一個新數組,長度爲最小容量。
return elementData = Arrays.copyOf(elementData,
newCapacity(minCapacity));
}
private Object[] grow() {
//增加的無參構造方法,返回一個新數組,長度爲當前元素個數+1。
return grow(size + 1);
}
private int newCapacity(int minCapacity) {
//newCapacity(min)是自動擴容方法。獲取元素數組的長度爲舊的容量,將新容量設置爲舊容量的1.5倍,若是舊容量爲0,那麼替換爲無參構造方法的空數組,若是擴容的長度溢出,那麼拋出超出內存異常。自動擴容返回擴容後的長度。
//若是新容量是合法的,那麼判斷是否小於等於最大數組長度,若是是則返回新長度,不然返回調用hugeCapacity(min)方法的結果。
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity <= 0) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
return Math.max(DEFAULT_CAPACITY, minCapacity);
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return minCapacity;
}
return (newCapacity - MAX_ARRAY_SIZE <= 0)
? newCapacity
: hugeCapacity(minCapacity);
}
private static int hugeCapacity(int minCapacity) {
//若是形參即原來長度就溢出的話,就拋出超出內存異常。不然判斷原來的大小和最大數組內存的長度,返回2^31-1或2^31-9。
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE)
? Integer.MAX_VALUE
: MAX_ARRAY_SIZE;
}
public int size() {
//返回實際元素個數
return size;
}
public boolean isEmpty() {
//判斷實際元素個數是否爲0
return size == 0;
}
public boolean contains(Object o) {
//查找元素o在數組中第一次出現的下標,若是爲-1就不存在。
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
//調用indexOfRange(查找對象,0,實際元素個數)
return indexOfRange(o, 0, size);
}
int indexOfRange(Object o, int start, int end) {
//在存儲元素的數組中查找,範圍是[start,end)。若是查找null對象,使用==比較。若是查找非null對象,那麼調用Object.equals()方法判斷是否相等。找到則返回下標,找不到返回-1。
Object[] es = elementData;
if (o == null) {
for (int i = start; i < end; i++) {
if (es[i] == null) {
return i;
}
}
} else {
for (int i = start; i < end; i++) {
if (o.equals(es[i])) {
return i;
}
}
}
return -1;
}
public int lastIndexOf(Object o) {
//調用lastIndexOfRange()
return lastIndexOfRange(o, 0, size);
}
int lastIndexOfRange(Object o, int start, int end) {
//與indexOfRange()相似,可是是逆序查找。
Object[] es = elementData;
if (o == null) {
for (int i = end - 1; i >= start; i--) {
if (es[i] == null) {
return i;
}
}
} else {
for (int i = end - 1; i >= start; i--) {
if (o.equals(es[i])) {
return i;
}
}
}
return -1;
}
public Object clone() {
//調用父類的clone()方法,而且轉換爲(ArrayList<?>)類型,新對象的數組複製原來的數組,並將新對象的修改次數設置爲0。若是克隆失敗,拋出CloneNotSupportedException。E
try {
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
public Object[] toArray() {
//返回元素數組的複製。
return Arrays.copyOf(elementData, size);
}
public <T> T[] toArray(T[] a) {
//泛型類型的數組複製。若是傳入數組的長度小於實際元素個數,那麼返回泛型數組類型的,列表中元素數組的複製。若是相等,直接複製,若是傳入數組的長度大於實際元素個數,多餘的位置用null填充。
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}E elementData(int index) {//以泛型類型返回數組中指定位置的元素 return (E) elementData[index];
}
@SuppressWarnings("unchecked")
static <E> E elementAt(Object[] es, int index) {
//以泛型類型返回給定數組中指定位置的元素
return (E) es[index];
}
public E get(int index) {
//泛型方法get()首先調用Objects工具類中的checkIndex()方法,判斷index是否在數組有效範圍內。該方法其實是另外一個定義相同的方法的調用,若是不在範圍內,拋出OutOfBoundsCheckIndex異常。不然返回下標對應的元素。
Objects.checkIndex(index, size);
return elementData(index);
}
public E set(int index, E element) {
//泛型方法set()首先判斷是否越界。不越界就修改下標處元素的值,並返回原來下標處的值。
Objects.checkIndex(index, size);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
private void add(E e, Object[] elementData, int s) {
//若是當前元素個數和長讀相等,那麼自動擴容一個長度。放入元素並使size++。
if (s == elementData.length)
elementData = grow();
elementData[s] = e;
size = s + 1;
}
public boolean add(E e) {
//修改次數+1,調用add()重載方法,返回true。
modCount++;
add(e, elementData, size);
return true;
}
public void add(int index, E element) {
//調用rangeCheckForAdd()
rangeCheckForAdd(index);
modCount++;
final int s;
Object[] elementData;
if ((s = size) == (elementData = this.elementData).length)
elementData = grow();
System.arraycopy(elementData, index,
elementData, index + 1,
s - index);
elementData[index] = element;
size = s + 1;
}
public E remove(int index) {
//首先判斷index是否合法,若是合法,定義一個final數組等於當前元素數組,而後保留泛型元素,調用fastRemove(),並將泛型元素返回。
Objects.checkIndex(index, size);
final Object[] es = elementData;
@SuppressWarnings("unchecked") E oldValue = (E) es[index];
fastRemove(es, index);
return oldValue;
}
public boolean equals(Object o) {
//若是是同一個對象,返回true。若是不是List或其子類,返回false。若是是,判斷對象的Clas是不是ArrayList,若是是就調用equalsArrayList()方法,不然調用equlsRange()方法
//最後調用checkForComodification()方法。
//在比較兩個List的過程當中不能改變List的元素。不然會拋出併發修改異常。
if (o == this) {
return true;
}
if (!(o instanceof List)) {
return false;
}
final int expectedModCount = modCount;
// ArrayList can be subclassed and given arbitrary behavior, but we can
// still deal with the common case where o is ArrayList precisely
boolean equal = (o.getClass() == ArrayList.class)
? equalsArrayList((ArrayList<?>) o)
: equalsRange((List<?>) o, 0, size);
checkForComodification(expectedModCount);
return equal;
}
boolean equalsRange(List<?> other, int from, int to) {
//首先定義靜態變量指向當前元素數組,若是範圍上界大於數組長度,就拋出併發修改異常(ArrayList線程不一樣步)。調用傳入List的迭代器,判斷每個元素是否相等,元素個數是否相等。一致返回true,不然返回false。
final Object[] es = elementData;
if (to > es.length) {
throw new ConcurrentModificationException();
}
var oit = other.iterator();
for (; from < to; from++) {
if (!oit.hasNext() || !Objects.equals(es[from], oit.next())) {
return false;
}
}
return !oit.hasNext();
}
private boolean equalsArrayList(ArrayList<?> other) {
//若是是兩個ArrayList判斷,先判斷兩個al的元素個數是否相等,若是相等,靜態定義兩個數組保存元素數組。若是當前元素個數超過數組長度,拋出併發修改異常。
//不然判斷每一個元素是否相等。最後調用checkForComodification()方法。返回判斷結果。
final int otherModCount = other.modCount;
final int s = size;
boolean equal;
if (equal = (s == other.size)) {
final Object[] otherEs = other.elementData;
final Object[] es = elementData;
if (s > es.length || s > otherEs.length) {
throw new ConcurrentModificationException();
}
for (int i = 0; i < s; i++) {
if (!Objects.equals(es[i], otherEs[i])) {
equal = false;
break;
}
}
}
other.checkForComodification(otherModCount);
return equal;
}
private void checkForComodification(final int expectedModCount) {
//判斷列表的修改次數是否相等。(主要用於多線程時)
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
public int hashCode() {
//調用hashCodeRange()方法,再判斷列表有沒有修改,若是修改拋出併發修改異常。返回hash值。
int expectedModCount = modCount;
int hash = hashCodeRange(0, size);
checkForComodification(expectedModCount);
return hash;
}
int hashCodeRange(int from, int to) {
//若是元素個數大於數組長度,拋出併發修改異常。定義hash初值爲1,遍歷每一個數組元素,以31進制的方式返回hash和(數組元素爲null時返回0)。返回hash和就是lisr的hash值。
final Object[] es = elementData;
if (to > es.length) {
throw new ConcurrentModificationException();
}
int hashCode = 1;
for (int i = from; i < to; i++) {
Object e = es[i];
hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
}
return hashCode;
}
public boolean remove(Object o) {
//定義一個標記found,若是找到一個相等的元素就終止此次循環,但不從新進入循環。即找到第一個相等的元素,調用fastRemove(),並返回true。若是循環沒有找到就返回false。
//注意若是o是整型,ArrayList會調用刪除指定下標方法。由於它是適合更小範圍的。
//迭代器遍歷時不能調用remove方法,會引發併發修改異常。
final Object[] es = elementData;
final int size = this.size;
int i = 0;
found: {
if (o == null) {
for (; i < size; i++)
if (es[i] == null)
break found;
} else {
for (; i < size; i++)
if (o.equals(es[i]))
break found;
}
return false;
}
fastRemove(es, i);
return true;
}
private void fastRemove(Object[] es, int i) {
//修改次數++,若是不是刪除最後一個元素,就複製後面的元素到前面。將最後一個元素賦值爲null,將size-1。
modCount++;
final int newSize;
if ((newSize = size - 1) > i)
System.arraycopy(es, i + 1, es, i, newSize - i);
es[size = newSize] = null;
}
public void clear() {
//修改次數++,將元素數組全賦值爲null,同時size賦值爲0。
modCount++;
final Object[] es = elementData;
for (int to = size, i = size = 0; i < to; i++)
es[i] = null;
}
public boolean addAll(Collection<? extends E> c) {
//修改次數++,判斷c轉爲數組的長度是否爲0。若是爲0直接返回false。若是數組剩餘長度不足集合元素個數,擴容至恰好足夠。將數組複製到元素數組彙總,修改size爲當前個數,返回true。
Object[] a = c.toArray();
modCount++;
int numNew = a.length;
if (numNew == 0)
return false;
Object[] elementData;
final int s;
if (numNew > (elementData = this.elementData).length - (s = size))
elementData = grow(s + numNew);
System.arraycopy(a, 0, elementData, s, numNew);
size = s + numNew;
return true;
}
public boolean addAll(int index, Collection<? extends E> c) {
//調用rangeCheckForAdd(),修改次數++,與addAll()重載方法相似,是從index處插入。
rangeCheckForAdd(index);
Object[] a = c.toArray();
modCount++;
int numNew = a.length;
if (numNew == 0)
return false;
Object[] elementData;
final int s;
if (numNew > (elementData = this.elementData).length - (s = size))
elementData = grow(s + numNew);
int numMoved = s - index;
if (numMoved > 0)
System.arraycopy(elementData, index,
elementData, index + numNew,
numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
size = s + numNew;
return true;
}
protected void removeRange(int fromIndex, int toIndex) {
//若是下界大於上界,拋出數組下標越界異常。不然修改次數++,調用shiftTrailOverGap()方法。
if (fromIndex > toIndex) {
throw new IndexOutOfBoundsException(
outOfBoundsMsg(fromIndex, toIndex));
}
modCount++;
shiftTailOverGap(elementData, fromIndex, toIndex);
}