1. 概述

在本篇文章中,我们将重点分析 Java 中 ArrayListVector 的区别。这两个类都属于 Java 集合框架,并且都实现了 java.util.List 接口。

不过,它们在实现层面存在显著差异。

2. 主要差异一览

先快速过一下两者的几个核心差异点,后续我们会逐个深入探讨:

  • 线程安全(Synchronization)Vector 是线程安全的,而 ArrayList 不是。
  • 扩容机制(Size Growth):当容量不足时,Vector 会将容量翻倍,而 ArrayList 只增加 50%。
  • 迭代方式(Iteration)Vector 支持 IteratorEnumeration 两种遍历方式,而 ArrayList 只支持 Iterator
  • 性能(Performance):由于同步机制的存在,Vector 的操作通常比 ArrayList 慢。
  • 框架归属(Framework)ArrayList 是集合框架的一部分,从 JDK 1.2 开始引入;而 Vector 是早期版本中的遗留类。

3. Vector 简介

由于我们已经有详细的 ArrayList 教程,这里不再赘述其 API 和使用方法。我们主要来看 Vector 的一些关键特性。

简单来说,**Vector 是一个可变大小的数组**,它可以根据元素的增删自动调整容量。

创建一个 Vector 的方式如下:

Vector<String> vector = new Vector<>();

默认构造器会创建一个初始容量为 10 的空 Vector

添加几个元素:

vector.add("baeldung");
vector.add("Vector");
vector.add("example");

使用 Iterator 进行遍历:

Iterator<String> iterator = vector.iterator();
while (iterator.hasNext()) {
    String element = iterator.next();
    // ...
}

或者使用 Enumeration 遍历:

Enumeration e = vector.elements();
while(e.hasMoreElements()) {
    String element = e.nextElement();
    // ... 
}

接下来,我们更深入地探讨其中几个关键点。

4. 并发处理

前面我们提到 Vector 是线程安全的,而 ArrayList 不是。现在我们来看一下具体原因。

如果你查看 Vector 的源码,会发现它的大部分方法都使用了 synchronized 关键字:

public synchronized E get(int index)

这意味着同一时间只有一个线程可以访问某个 Vector 实例的方法。

⚠️ 但要注意,这种“方法级同步”并不足以保证复合操作的线程安全。比如多个步骤组合的操作(如先检查再插入),仍然需要我们自己加锁来保证原子性。

相比之下,ArrayList 的方法没有同步机制,线程安全的责任交给了开发者。

如果需要线程安全的 ArrayList,可以使用如下替代方案:

vector.get(1); // synchronized
Collections.synchronizedList(arrayList).get(1); // 同样是同步的

或者使用更现代的并发集合类,比如:

  • CopyOnWriteArrayList
  • Collections.synchronizedList()

5. 性能对比

由于 Vector 的同步机制,它的性能通常比 ArrayList 差很多。

为了直观对比两者的性能差异,我们使用 JMH 编写了一个简单的基准测试。

5.1 get() 方法性能测试

@Benchmark
public Employee testGet(ArrayListBenchmark.MyState state) {
    return state.employeeList.get(state.employeeIndex);
}

@Benchmark
public Employee testVectorGet(ArrayListBenchmark.MyState state) {
    return state.employeeVector.get(state.employeeIndex);
}

测试配置为 3 个线程,10 次预热迭代,结果如下:

Benchmark                         Mode  Cnt   Score   Error  Units
ArrayListBenchmark.testGet        avgt   20   9.786 ± 1.358  ns/op
ArrayListBenchmark.testVectorGet  avgt   20  37.074 ± 3.469  ns/op

可以看出,ArrayList#get() 的速度大约是 Vector#get() 的 3 倍。

5.2 contains() 方法性能测试

@Benchmark
public boolean testContains(ArrayListBenchmark.MyState state) {
    return state.employeeList.contains(state.employee);
}

@Benchmark
public boolean testContainsVector(ArrayListBenchmark.MyState state) {
    return state.employeeVector.contains(state.employee);
}

结果如下:

Benchmark                              Mode  Cnt  Score   Error  Units
ArrayListBenchmark.testContains        avgt   20  8.665 ± 1.159  ns/op
ArrayListBenchmark.testContainsVector  avgt   20  36.513 ± 1.266  ns/op

✅ 同样地,Vectorcontains() 方法耗时也远高于 ArrayList

6. 总结

本文我们详细对比了 Java 中 VectorArrayList 的区别,并深入分析了它们在并发处理、性能表现、扩容机制等方面的异同。

简单粗暴地说:

  • 如果你不需要线程安全,直接用 ArrayList
  • 如果需要线程安全,推荐使用 Collections.synchronizedList()CopyOnWriteArrayList,而不是 Vector

📌 完整代码示例可以在 GitHub 找到。


原始标题:Java ArrayList vs Vector | Baeldung