集合的作用就是以一定的方式組織,存儲數據。對於ArrayList,我認爲需要的關注以下內容:
1.集合的基本存儲單元
2.集合的增刪改查基本操作的實現
3.存儲數據的要求,是否爲空,是否允許重複
4.存放與讀取是否有序
5.是否線程安全
基本存儲單元
ArrayList的源碼片段:
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData; // non-private to simplify nested class access
private int size;
底層存放的是Object[]數組,size不是數組長度,單獨計算。
集合的增刪改查基本操作的實現
1.新增元素
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
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);
}
ensureCapacityInternal方法用於判斷數組是否需要擴容,底層調用grow方法繼續數組動態擴容,上面代碼擴容了1.5倍的長度。Arrays.copyOf方法會先創建一個長度爲newCapacity的數據,調用System.arraycopy將原先的elementData數據拷貝至新的數組中,這是順序插入的實現。
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++;
}
這是中間插入的實現,先判斷數組容量是否足夠,之後從index位置開始,利用System.arraycopy做一個整體的數據複製並向後位移一個位置,將需要插入的元素放置在index位置。如果集合中的數據比較龐大,而且需要的插入前半部分操作比較多,ArrayList的效率會很低。
2.修改元素
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
比較簡單,不詳細說明。
3.刪除元素
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;
}
刪除方法和中間插入的實現差不多,System.arraycopy將數組從index位置複製並向前位移一個單位,完成後將最後一個元素置爲null。
存儲數據的要求,是否爲空,是否允許重複
允許爲空或者null,允許重複
存放與讀取是否有序
底層實現是數組,所以有序
是否線程安全
非線程安全,因爲所有方法都是不同步的。如果需要線程安全,可以使用Vector,Vector裏的實現基本和ArrayList一致,每個方法都加入了synchronized,不同的地方是Vector多了一個增長因子capacityIncrement,數組擴容的時候回用到。
ArrayList的優缺點
優點:查找速度快,順序插入速度快,缺點:刪除和中間插入用到了數組拷貝,會影響性能。
適用場景:訪問比較頻繁,順序插入比較多的場景。