ArrayList是基於數組實現的一個有序的列表,容許添加null值.除了List接口中的方法外,還實現了一些操做數組元素和大小的方法,具體下面會列舉。每一個ArrayList實例都有一個元素數,即size屬性,這個屬性標註了在實例中包含了多少個元素,這些元素存儲在elementData這個數組中,當實例的容量不足時,會調用grow方法進行擴容,一般狀況下每次擴大一半容量,可是有兩種特殊狀況,一種是手動指定的容量大於當前容量的1.5倍時會按照指定容量擴容,另外一種是當前容量的1.5倍大於MAX_ARRAY_SIZE這個值的時候會擴容至Integer.MAX_VALUE或MAX_ARRAY_SIZE。
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public ArrayList(int initialCapacity) { //指定容量
if (initialCapacity > 0) { //指定容量>0,則按照指定的容量構建數組
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) { //指定容量=0,則構造默認空數組
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
}
}
public ArrayList(Collection<? extends E> c) { //經過一個集合構造數組
elementData = c.toArray();
if ((size = elementData.length) != 0) { //參數集合不爲空,則將實例構形成Object[]
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else { //參數集合爲空,則將實例構形成默認空數組
this.elementData = EMPTY_ELEMENTDATA;
}
}
public boolean add(E e) {
ensureCapacityInternal(size + 1); //擴容操做
elementData[size++] = e;
return true;
}
public void add(int index, E element) { //添加元素到指定位置
rangeCheckForAdd(index); //檢查index是否越界
ensureCapacityInternal(size + 1);
System.arraycopy(elementData, index, elementData, index + 1,size - index);
elementData[index] = element;
size++;
}
public boolean addAll(Collection<? extends E> c) { //將參數集合添加至實例
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew);
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
public boolean addAll(int index, Collection<? extends E> c) { //將參數集合添加至實例指定位置
rangeCheckForAdd(index); //檢查index是否越界
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index; //這裏要注意,插入前會將原數組從index位置分開
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
public E set(int index, E element) { //新增會將index位置以後的元素依次後移,而覆蓋會將index位置的元素替換,對其餘位置的元素沒有影響
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, //刪除元素以後會將index以後的元素依次向前一位
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++) //遍歷數組直到找到指定元素並刪除
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++) //遍歷數組直到找到指定元素並刪除
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
public void clear() {
modCount++;
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //當使用第一種構造方法時,第一次執行擴容方法會進入這個分支,將容量擴展爲默認大小(10)
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
if (minCapacity - elementData.length > 0) //若是參數長度大於數組長度則會擴容
grow(minCapacity);
}
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); //默認每次增加爲1.5倍
if (newCapacity - minCapacity < 0) //特例1:參數大於數組長度的1.5倍,此時按照參數擴容
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0) //特例2:數組長度的1.5倍大於MAX_ARRAY_SIZE,此時將數組擴容至MAX_ARRAY_SIZE 或Integer.MAX_VALUE
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}