1、構造方法
(1)public ArrayList():初始化一個容量爲空的容器
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
(2)ArrayList(int initialCapacity):初始化一個容量爲initialCapacity的容器
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
}
}
(3)ArrayList(Collection<? extends E> c):初始化一個具有一些元素的集合類。集合類容量爲添入元素個數。
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
2、常用方法
(1)add(Object obj):在容器後面添加元素。
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
(2)add(int index, Object obj):在指定位置添加元素。
首先檢查插入下標,然後確保容量。將插入點之後的元素向後移動一位。
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,size - index);
elementData[index] = element;
size++;
}
(3)addAll(Collection<? extends E> c)
在集合類末尾添加集合類。直接將添加的集合類轉化爲數組,複製到被添加的集合類末尾。
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
(4)addAll(int index, Collection<? extends E> c)
在某個位置添加集合類。首先將被添加的集合類的在index處分開,空出需要添加的個數,然後將添加的內容複製到空位
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
(5)remove(int index)
通過下標移除某個位置的元素。將該下標之後的元素向前移動一位,空出的末尾擲空,原來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,numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
(6)remove(Object o)
通過對象移除某個位置的元素。遍歷ArrayList,利用equals方法判斷是否相等,如果相等則移除。
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;
}
3、ArrayList擴容
ArrayList添加元素的時候,如果元素個數超過內部數組長度,則首先選擇擴充到原來的1.5倍,如果還不夠則擴充到添加後元素的個數。核心源碼如下:
minCapacity爲添加元素後集閤中元素總數。
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
4、Vector與ArrayList的區別
同ArrayList,唯一區別是Vector是線程安全的,ArrayList是線程安全的,內部擴容方式不一樣。
Vector擴容程度與擴容因子有關。初始化Vector的時候如果初始化擴容因子,則首先選擇擴容當前容量+擴容因子;如果沒有初始化擴容因子,則選擇擴容當前容量的2倍。核心代碼如下:
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}