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

Vector vs ArrayList 深度對比:線程安全、擴容策略與性能選型

     編輯:Java 相關知識

核心差異速覽

特性ArrayListVector
線程安全非線程安全所有方法 synchronized,線程安全
擴容倍數1.5 倍 + 1(newCapacity = old*3/2+1)2 倍(或指定 capacityIncrement)
性能高(無鎖開銷)低(同步鎖開銷大)
遍歷速度快(RandomAccess + 連續內存)同 ArrayList
插入/刪除中間慢(需數組複製移動)同 ArrayList
推薦場景單線程、高頻隨機訪問、作為首選 List 實現極少見,僅維護舊代碼或極簡單多線程場景

源碼級擴容機制分析

ArrayList (JDK 17)

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

Vector (JDK 17)

public synchronized boolean add(E e) {
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = e;
    return true;
}
private void ensureCapacityHelper(int minCapacity) {
    if (minCapacity - elementData.length > 0) {
        int oldCapacity = elementData.length;
        int newCapacity = (capacityIncrement > 0) ?
            oldCapacity + capacityIncrement : oldCapacity * 2; // 默認 2倍
        if (newCapacity - minCapacity < 0) newCapacity = minCapacity;
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
}

為什麼不推薦 Vector?

  1. 鎖粒度過粗:每個方法加鎖,即使單線程也承擔進入/退出監視器開銷。
  2. 替代方案更優:多線程環境首選 Collections.synchronizedList(new ArrayList<>()) 或並發包 CopyOnWriteArrayList(讀多寫少) / ConcurrentLinkedQueue(隊列語義)。
  3. 擴容策略固定 2 倍,記憶體浪費可能大於 ArrayList 的 1.5 倍。

LinkedList 補充對比

  • 底層雙向鏈表,首尾增刪 O(1),適合棧/隊列/雙端隊列。
  • 隨機訪問 O(n),不實現 RandomAccess,遍歷建議用迭代器或 for-each。
  • 記憶體佔用大(每節點額外 2 引用 + 對象頭)。

選型決策樹

需要線程安全?
 ├─ 是 → 讀多寫少 → CopyOnWriteArrayList
 │        寫多或需併發隊列 → ConcurrentLinkedQueue / 並發包其他結構
 └─ 否 → 需頻繁中間增刪 → LinkedList
          預設首選 → ArrayList
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved