博客 / 詳情

返回

藍易雲cdn:ArrayList和Vector及Vector的區別

結論先拋出來:在今天的 Java 項目裏,絕大多數場景都應該用 <span style="color:red">ArrayList</span>,而不是 <span style="color:red">Vector</span>。<span style="color:red">Vector 基本已經是“歷史兼容”角色</span>,只在極少數老系統或特殊場景才需要保留。🙂


一、ArrayList 和 Vector 的共同點(先把基礎打牢)

兩者本質上都是基於動態數組的順序容器:(Oracle 文檔)

  • 底層結構:都用數組存儲元素,支持下標隨機訪問,get(index) 是 <span style="color:red">O(1)</span> 級別。
  • 元素特性:都允許存放重複元素,也允許 null
  • 接口層面:都實現了 <span style="color:red">List 接口</span>,支持 add / remove / get / set / iterator 等常規操作。

也就是説,從“能幹什麼”上看,兩者幾乎一模一樣,真正的差別在於:併發模型 + 擴容策略 + 歷史定位


二、核心差異對比表(vditor 可直接渲染)🚀

| 特性 | ArrayList | Vector | 説明 |
| --- | --- | --- | --- |
| 線程安全 | <span style="color:red">非線程安全</span> | <span style="color:red">線程安全(方法同步)</span> | Vector 所有關鍵方法都加了 synchronized,ArrayList 沒有。:contentReference[oaicite:1]{index=1} |
| 性能 | <span style="color:red">單線程場景更快</span> | 同步開銷導致整體更慢 | 無鎖 vs 有鎖的差異,在高併發讀取時尤其明顯。:contentReference[oaicite:2]{index=2} |
| 擴容策略 | 容量不足時一般按 <span style="color:red">1.5 倍</span> 擴容 | 默認按 <span style="color:red">2 倍</span> 擴容 | Vector 可能浪費更多內存,但擴容次數相對少。:contentReference[oaicite:3]{index=3} |
| 歷史定位 | <span style="color:red">Collections Framework 正式成員</span> | <span style="color:red">遺留類(legacy)</span> | 官方文檔明確説明 Vector 主要為兼容早期代碼而保留。:contentReference[oaicite:4]{index=4} |
| 遍歷方式 | 主要用 Iterator / for-each | 可用 Iterator 和 Enumeration | Enumeration 也是比較老的遍歷風格。:contentReference[oaicite:5]{index=5} |
| 實際推薦度 | <span style="color:red">新代碼默認首選</span> | 僅在維護老項目或極少數場景使用 | 行業實踐和最新教程都傾向推薦 ArrayList。:contentReference[oaicite:6]{index=6} |

三、重點差異拆解(為什麼 Vector 基本“退居二線”)⚙️

1. 線程安全 vs 性能

  • <span style="color:red">Vector:方法級同步</span>

    • 典型方法 add() / remove() / get() 都帶 synchronized
    • 好處:併發訪問時天然具備一定線程安全
    • 問題:鎖粒度粗,所有線程競爭同一把鎖,吞吐量和延遲都受影響。(GeeksforGeeks)
  • <span style="color:red">ArrayList:不做任何內置同步</span>

    • 適合絕大多數單線程或讀多寫少的典型業務代碼
    • 需要線程安全時,推薦:

      • Collections.synchronizedList(new ArrayList<>())
      • 或直接使用 <span style="color:red">CopyOnWriteArrayList</span> 等併發集合。(Oracle 文檔)

一句話:如果你不清楚是否需要鎖,大概率就是不需要 Vector 這種大錘。


2. 擴容策略與內存利用

  • <span style="color:red">ArrayList</span>:默認空間不夠時,容量變為原來的約 1.5 倍,兼顧擴容成本和內存佔用。(GeeksforGeeks)
  • <span style="color:red">Vector</span>:如果沒有單獨設置 capacityIncrement,容量不夠時直接翻倍

    • 優點:擴容次數更少。
    • 缺點:在元素體積較大、數據量多變時,容易造成內存浪費和 GC 壓力。

對大部分業務系統而言,ArrayList 的 1.5 倍擴容更温和,更符合“夠用就好”的資源策略。


3. “遺留類”定位與生態支持

官方文檔已經明確説明:<span style="color:red">ArrayList 大致等價於一個無同步版本的 Vector</span>,而 Vector 現在主要是為了兼容早期 Java 代碼而存在。(Oracle 文檔)

這意味着:

  • 新框架、新第三方庫、新示例代碼,幾乎全都站在 <span style="color:red">ArrayList</span> 陣營。
  • Vector 更多出現在“老系統重構”“維護舊代碼”場景,很少出現在新架構設計裏。😅

四、實戰選型建議(給你一個簡單決策規則)✅

可以直接套用下面這條“土規矩”:

  1. 絕大部分新業務列表結構
    → 直接用 <span style="color:red">ArrayList</span>。
  2. 確實有多線程寫入 + 讀寫混合 + 數據量不大
    → 用 Collections.synchronizedList(new ArrayList<>()) 或 <span style="color:red">CopyOnWriteArrayList</span>。
  3. 維護老項目,裏面到處是 Vector
    → 在不改變行為的前提下,可以逐步封裝、限流、按模塊局部替換,避免一次性大動手術。

五、代碼示例 + 逐行解釋 🧩

下面是一個簡單對比示例,展示 <span style="color:red">ArrayList</span>、<span style="color:red">Vector</span> 以及“同步包裝”的使用方式:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Vector;

public class ListDemo {
    public static void main(String[] args) {
        // 1. 非線程安全的 ArrayList(新項目默認首選)
        List<String> arrayList = new ArrayList<>();

        // 2. 線程安全的 Vector(更偏向遺留代碼)
        List<String> vector = new Vector<>();

        // 3. 對 ArrayList 做同步包裝,獲得線程安全版本
        List<String> syncList = Collections.synchronizedList(new ArrayList<>());

        arrayList.add("BlueEasy");
        vector.add("BlueEasy");
        syncList.add("BlueEasy");
    }
}

逐行説明:

  • import java.util.ArrayList;
    引入 <span style="color:red">ArrayList</span> 類,用於創建動態數組實現的 List。
  • import java.util.Collections;
    引入工具類 Collections,裏面提供了 synchronizedList 等靜態方法,可以給非線程安全集合加同步包裝。
  • import java.util.List;
    引入 List 接口,後續變量統一面向接口編程,方便替換實現。
  • import java.util.Vector;
    引入 <span style="color:red">Vector</span> 類,用於展示傳統同步 List 的寫法。
  • public class ListDemo { ... }
    定義一個簡單示例類 ListDemo,用於演示三種 List 的用法。
  • public static void main(String[] args) { ... }
    標準入口方法,JVM 從這裏開始執行示例代碼。
  • List<String> arrayList = new ArrayList<>();
    創建一個基於 <span style="color:red">ArrayList</span> 的字符串列表:

    • 不帶任何鎖,性能好,適合單線程或外部自己控制同步的場景。
  • List<String> vector = new Vector<>();
    創建一個基於 <span style="color:red">Vector</span> 的字符串列表:

    • 所有常規操作內部都有 synchronized,在多線程場景能避免部分併發問題,但性能開銷較大。
  • List<String> syncList = Collections.synchronizedList(new ArrayList<>());
    把一個新的 <span style="color:red">ArrayList</span> 用 Collections.synchronizedList 包裝:

    • 外層返回的 syncList 對象是線程安全的。
    • 實際底層仍是 ArrayList,但所有訪問都通過同步包裝層。
  • arrayList.add("BlueEasy");
    向普通 ArrayList 添加字符串 "BlueEasy"無鎖、速度快
  • vector.add("BlueEasy");
    向 Vector 添加元素,這個調用內部會先獲取鎖,再執行插入操作,保證一定線程安全。
  • syncList.add("BlueEasy");
    向同步包裝後的 ArrayList 添加元素,本質上等價於對 ArrayList 調用加鎖後的 add

六、思維導圖式小結(文字版)

ArrayList vs Vector
├── 共同點
│   ├── 基於動態數組
│   ├── 隨機訪問 O(1)
│   └── 實現 List 接口
├── 核心差異
│   ├── 線程安全:ArrayList 非同步,Vector 方法級同步
│   ├── 擴容策略:ArrayList ~1.5 倍,Vector 默認 2 倍
│   ├── 歷史定位:ArrayList 新框架一等公民,Vector 遺留類
│   └── 遍歷方式:Vector 還支持 Enumeration
└── 實戰選型
    ├── 新項目:優先 ArrayList
    ├── 需要線程安全:同步包裝或併發集合
    └── 老項目:逐步從 Vector 遷移

一句硬核又現實的總結:
如果只是日常業務開發,還在糾結用 <span style="color:red">Vector</span>,基本就是在給自己找性能和維護成本的麻煩;新項目直接用 <span style="color:red">ArrayList</span> + 合理的併發集合,才是符合當下工程實踐的選擇。 💼

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.