Skip to content

Vector 和 Stack:过时的 API 以及替代方案

一句话警告

Vector 和 Stack 已被废弃。它们是 JDK 1.0 的遗留代码,在性能和设计上都有问题。现代 Java 代码不应该再使用它们。


Vector vs ArrayList:有什么区别

Vector 几乎是 ArrayList 的「同步版本」:

java
// Vector:所有方法都 synchronized
public class Vector<E> {
    public synchronized boolean add(E e) { ... }
    public synchronized E get(int index) { ... }
    public synchronized E set(int index, E e) { ... }
    // ...
}

// ArrayList:方法不带 synchronized
public class ArrayList<E> {
    public boolean add(E e) { ... } // 没有 synchronized
    public E get(int index) { ... } // 没有 synchronized
}

扩容机制也不同

特性VectorArrayList
默认容量100(首次添加时才 10)
扩容倍数2 倍1.5 倍
线程安全是(synchronized)

Stack 的继承问题

Stack 继承自 Vector,这是设计上的一个大问题:

java
public class Stack<E> extends Vector<E> { ... }

继承 Vector 意味着 Stack 拥有了 Vector 的所有方法,包括按索引访问、按位置插入等——这些「超能力」对栈来说是不应该有的。

java
Stack<String> stack = new Stack<>();

stack.push("A");
stack.push("B");

// ❌ Stack 继承自 Vector,所以这些方法也存在:
stack.get(0);           // 栈不应该能按索引访问
stack.add(0, "C");     // 栈不应该能在中间插入
stack.remove(0);         // 栈不应该能按索引删除

一个好的设计应该是「组合优于继承」。


三种替代方案

替代 1:ArrayDeque(推荐用于栈/队列)

java
// ✅ Stack 替换为 ArrayDeque
Deque<Integer> stack = new ArrayDeque<>();

stack.push(1);
stack.push(2);
stack.push(3);

System.out.println("栈顶: " + stack.peek());    // 3
System.out.println("出栈: " + stack.pop());     // 3
System.out.println("栈顶: " + stack.peek());    // 2

性能对比:

ArrayDeque.push/pop: ~5 ms(10 万元素)
Stack.push/pop: ~15 ms

替代 2:LinkedList(需要 Queue 功能时)

java
// ✅ 队列和栈都可以用 LinkedList
Deque<String> stack = new LinkedList<>();
Deque<String> queue = new LinkedList<>();

// 作为栈
stack.push("A");
stack.pop();

// 作为队列
queue.offer("A");
queue.poll();

替代 3:双端队列(JDK 6+ 的 Deque)

java
// ✅ Deque 接口,明确支持栈和队列操作
Deque<Integer> deque = new ArrayDeque<>();

// 栈操作
deque.push(1);
deque.pop();

// 队列操作
deque.offerLast(1);
deque.pollFirst();

迁移指南

从 Stack 迁移到 ArrayDeque

java
// ❌ 旧代码
Stack<Order> orderStack = new Stack<>();
while (hasMoreOrders()) {
    orderStack.push(processOrder());
}

// ✅ 新代码
Deque<Order> orderStack = new ArrayDeque<>();
while (hasMoreOrders()) {
    orderStack.push(processOrder());
}

从 Vector 迁移到 ArrayList

java
// ❌ 旧代码
Vector<String> old = new Vector<>();
old.add("a");
synchronized (old) {
    for (String s : old) {
        System.out.println(s);
    }
}

// ✅ 新代码:单线程用 ArrayList
List<String> list = new ArrayList<>();
list.add("a");
for (String s : list) {
    System.out.println(s);
}

// ✅ 多线程用 CopyOnWriteArrayList 或 synchronizedList
List<String> safe = new CopyOnWriteArrayList<>();
// 或
List<String> safe2 = Collections.synchronizedList(new ArrayList<>());

什么时候还在用 Vector/Stack

坦率地说:几乎不应该用。但如果遇到遗留代码需要维护,记住:

场景建议
新代码永远不要用
遗留代码维护找机会迁移到 ArrayDeque
线程安全需求用 Collections.synchronizedList 或 CopyOnWriteArrayList

总结

特性VectorStackArrayListArrayDeque
线程安全✅(继承自 Vector)
性能差(全局锁)最好
扩容倍数2 倍2 倍1.5 倍2 倍
推荐程度不推荐不推荐✅ 推荐最推荐

相关链接

基于 VitePress 构建