transient Object[] elementData; // transient: 不序列化陣列本身,由 writeObject 手動處理 int size; // 實際元素數量 int modCount; // 修改次數 (fail-fast 機制用)
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; // 共享空陣列實例
}
**延遲初始化**:真正添加第一個元素時才分配大小 10 的陣列。
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);
}
}
**最佳實務**:預估資料量,指定初始容量避免多次擴容複製。
public ArrayList(Collection extends E> c) {
elementData = c.toArray();
size = elementData.length;
// 防護性複製:確保底層陣列為 Object[]
if (elementData.getClass() != Object[].class) {
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
}
public boolean add(E e) {
ensureCapacityInternal(size + 1); // 確保容量
elementData[size++] = e; // 賦值並遞增 size
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // 至少 10
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
if (minCapacity > elementData.length) {
grow(minCapacity); // 觸發擴容
}
}
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5 倍擴容
if (newCapacity < minCapacity) newCapacity = minCapacity;
if (newCapacity > MAX_ARRAY_SIZE) newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
| 項目 | 說明 |
|---|---|
| 擴容倍率 | 1.5 倍 (`oldCapacity + oldCapacity/2`) |
| 觸發時機 | `size + 1 > elementData.length` |
| 複製方法 | `Arrays.copyOf` (native 實作,極快) |
| 最大容量 | `Integer.MAX_VALUE - 8` (約 21 億) |
| 預設初始容量 | 10 (JDK 8+ 延遲到首次 add 才分配) |
public E get(int index) {
rangeCheck(index); // 邊界檢查
return elementData(index); // 直接陣列存取
}
private void rangeCheck(int index) {
if (index >= size) throw new IndexOutOfBoundsException(...);
}
public void add(int index, E element) {
rangeCheckForAdd(index); // 允許 index == size (尾部插入)
ensureCapacityInternal(size + 1);
System.arraycopy(elementData, index, // 來源陣列、來源起始
elementData, index + 1, // 目標陣列、目標起始
size - index); // 複製長度
elementData[index] = element;
size++;
}
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; // 釋放引用助 GC
return oldValue;
}
// 同步包裝器 (效能較差) ListsyncList = Collections.synchronizedList(new ArrayList<>()); // 並發專用 (JDK 5+ 推薦) List concurrentList = new CopyOnWriteArrayList<>(); // 讀多寫少 // 或 List concurrentList = Collections.synchronizedList(new ArrayList<>()); // 一般同步
下篇將深入解析:`iterator()` 實作與 fail-fast 機制、`subList` 視圖陷阱、`toArray` 陷阱、`removeIf`、`replaceAll` 等 JDK 8+ 新方法源碼。