首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

ArrayList 核心源碼深度解析:動態擴容、泛型實現、性能優化與最佳實踐

     編輯:Java 程式設計入門

ArrayList 本質

實現 List 接口、基於動態數組、支持隨機訪問。底層封裝 Object[] elementData,默認初始容量 10(JDK 8+ 延遲初始化至首次 add)。

核心構造器

public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
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 c) {
    elementData = c.toArray();
    if ((size = elementData.length) != 0) {
        if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else elementData = EMPTY_ELEMENTDATA;
}

擴容機制:核心性能影響點

public boolean add(E e) {
    ensureCapacityInternal(size + 1);
    elementData[size++] = e;
    return true;
}
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, 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) newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);
}

擴容成本分析

  • 數組複製:Arrays.copyOf 為 O(n) 操作。
  • 觸發頻率:默認 10 → 15 → 22 → 33 → 49 → 73 → 109…
  • 預估容量:new ArrayList<>(預估大小) 避免多次擴容複製,大幅提升批量插入性能。

TrimToSize

trimToSize() 將容量縮減至 size,釋放未用內存,適用於元素固定不再增刪的場景。

關鍵操作時間複雜度

操作複雜度說明
get(index) / set(index, e)O(1)數組隨機訪問優勢
add(e) 尾部均攤 O(1)偶爾觸發擴容 O(n)
add(index, e) / remove(index)O(n)需移動後續元素,索引越前開銷越大
contains / indexOf / remove(Object)O(n)線性掃描,無索引優化

泛型與類型擦除