一、什么是 Vector
Vector 是 java.util 包下的老牌类(JDK1.0 就存在),同样实现了 List 接口,本质也是动态扩容的数组,核心区别是:
- 所有核心方法(如
add、remove、get)都加了synchronized关键字,是线程安全的。 - 底层基于数组实现,特性和
ArrayList类似(有序、可重复、允许null),但性能比ArrayList低。
二、核心用法(完整示例代码)
Vector 的 API 和 ArrayList 高度兼容,用法几乎一致,代码可直接运行:
import java.util.Iterator;
import java.util.Vector;
public class VectorDemo {
public static void main(String[] args) {
// 1. 创建 Vector 对象(指定泛型,避免类型转换)
// 方式1:默认初始化,初始容量10
Vector<String> vector = new Vector<>();
// 方式2:指定初始容量(推荐,减少扩容)
// Vector<String> vector = new Vector<>(20);
// 方式3:指定初始容量 + 扩容增量
// Vector<String> vector = new Vector<>(10, 5); // 满了之后每次扩容5个位置
// 2. 添加元素
vector.add("Java"); // 末尾添加
vector.add("Python");
vector.add(1, "C++"); // 指定索引添加,元素后移
System.out.println("添加后:" + vector); // 输出:[Java, C++, Python]
// 3. 获取元素
String first = vector.get(0);
System.out.println("第一个元素:" + first); // 输出:Java
// 4. 修改元素
vector.set(2, "Go");
System.out.println("修改后:" + vector); // 输出:[Java, C++, Go]
// 5. 删除元素
vector.remove(1); // 按索引删除
vector.remove("Go"); // 按元素值删除
System.out.println("删除后:" + vector); // 输出:[Java]
// 6. 遍历元素(和 ArrayList 一致)
// 方式1:普通for循环
System.out.println("普通for循环遍历:");
for (int i = 0; i < vector.size(); i++) {
System.out.println(vector.get(i));
}
// 方式2:增强for循环
System.out.println("增强for循环遍历:");
for (String s : vector) {
System.out.println(s);
}
// 方式3:迭代器
System.out.println("迭代器遍历:");
Iterator<String> it = vector.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
// 7. 其他常用方法
int size = vector.size(); // 获取元素个数
boolean isEmpty = vector.isEmpty(); // 判断是否为空
boolean contains = vector.contains("Java"); // 判断是否包含元素
vector.clear(); // 清空所有元素
}
}
三、关键特性解析
1. 扩容机制(和 ArrayList 不同)
- 默认初始容量:10。
- 扩容规则(核心区别):
- 如果创建时未指定扩容增量:扩容后容量 = 原容量 × 2(比如 10→20→40);
- 如果创建时指定了扩容增量 (如
new Vector(10,5)):扩容后容量 = 原容量 + 增量(10→15→20)。
- 对比:
ArrayList扩容是原容量的 1.5 倍,Vector扩容幅度更大,更易浪费内存。
2. 线程安全的实现方式
Vector 的线程安全是通过给核心方法加 synchronized 关键字实现的,比如:
// Vector 的 add 方法源码(简化版)
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
这种方式虽然保证了线程安全,但性能损耗大(每次调用方法都要加锁),高并发场景下效率很低。
3. 迭代器特性
Vector 除了普通的 Iterator,还提供了专属的 Enumeration(枚举),用法和迭代器类似,但功能更简单(仅支持遍历,不支持删除):
import java.util.Enumeration;
import java.util.Vector;
public class VectorEnumeration {
public static void main(String[] args) {
Vector<String> vector = new Vector<>();
vector.add("a");
vector.add("b");
// 使用 Enumeration 遍历
Enumeration<String> en = vector.elements();
while (en.hasMoreElements()) {
System.out.println(en.nextElement());
}
}
}
四、Vector vs ArrayList(核心对比)
这是最常考的知识点,用表格清晰对比:
| 特性 | Vector | ArrayList |
|---|---|---|
| 线程安全 | 线程安全(方法加 synchronized) | 非线程安全 |
| 扩容规则 | 默认扩容 2 倍(可指定增量) | 默认扩容 1.5 倍 |
| 性能 | 低(锁开销) | 高(无锁) |
| 迭代器 / 枚举 | 支持 Iterator + Enumeration | 仅支持 Iterator |
| 诞生版本 | JDK1.0(古老) | JDK1.2(集合框架统一规范) |
| 适用场景 | 低并发的线程安全场景 | 单线程 / 无并发读写场景 |
五、使用建议(避坑指南)
- 不推荐优先使用 Vector :即使需要线程安全的 List,也不建议用
Vector,因为它的锁粒度太大(整个方法加锁),性能差。替代方案:- 低并发:
Collections.synchronizedList(new ArrayList<>())(给 ArrayList 加全局锁); - 高并发读、低并发写:
CopyOnWriteArrayList(写时复制,读无锁,性能远高于 Vector)。
- 低并发:
- 扩容增量优化 :如果必须用
Vector,建议创建时指定初始容量和扩容增量,避免频繁扩容和内存浪费。 - 遍历删除注意 :和
ArrayList一样,增强 for 循环中直接删除会抛ConcurrentModificationException,需用迭代器的it.remove()。
总结
Vector是线程安全的动态数组,通过synchronized关键字实现,但性能低于ArrayList,扩容默认 2 倍(可指定增量)。Vector和ArrayList核心 API 兼容,但诞生更早、性能更差,仅适用于低并发的线程安全场景。- 线程安全的 List 优先选择
CopyOnWriteArrayList(高并发)或Collections.synchronizedList(低并发),而非Vector。
