vector 的 add() 方法比 arraylist 慢,因为其默认同步导致每次调用都进入 synchronized 块,而 arraylist 无锁且扩容为1.5倍更省内存;遍历时应统一用 iterator() 而非 elements(),后者返回非 iterable 的 enumeration;vector 的复合操作仍线程不安全,现代开发应优先选用 arraylist 或并发集合。

Vector 的 add() 方法为什么比 ArrayList 慢
因为 Vector.add() 默认是同步的,每个调用都走 synchronized 块,哪怕你只在单线程里用它。而 ArrayList.add() 完全没锁,扩容时也只是普通数组复制。
实操建议:
- 除非明确需要线程安全的动态数组,否则别用
Vector—— 它不是“更老版的 ArrayList”,而是设计目标不同的类 - 多线程下真要同步 list,优先用
Collections.synchronizedList(new ArrayList()),它把同步粒度控制在方法层,且可选是否包装读操作 -
Vector扩容是翻倍(oldCapacity * 2),ArrayList是oldCapacity + (oldCapacity >> 1)(即 1.5 倍),前者更容易浪费内存
Vector 的 elements() 返回 Enumeration 而不是 Iterator
这是遗留接口,elements() 返回的是 Enumeration,不能用增强 for 循环,也不支持 remove() 操作;而 ArrayList 的 iterator() 返回标准 Iterator,支持 remove() 和 forEachRemaining()。
常见错误现象:写 for (Object o : vector.elements()) 直接编译失败,因为 Enumeration 不实现 Iterable。
实操建议:
- 遍历时统一用
vector.iterator(),它和ArrayList.iterator()行为一致,且返回的Iterator是 fail-fast 的 - 别依赖
elements(),它只在极老代码或对接java.util.Stack(继承自Vector)时才可能遇到 -
Enumeration不抛ConcurrentModificationException,但也不保证遍历一致性 —— 这反而更危险
Vector 在多线程下仍可能出错的场景
Vector 的每个方法是原子的,但复合操作不是线程安全的。比如 if (!vector.contains(x)) vector.add(x),两个线程同时执行,可能都通过判断、都 add,结果重复插入。
性能影响:即使加了 synchronized,JVM 对粗粒度锁的优化有限,高并发下容易形成锁争用,吞吐量远低于 CopyOnWriteArrayList 或 ConcurrentHashMap 配合使用。
实操建议:
- 检查代码里有没有“先查后改”这类模式,它们在
Vector里照样不安全 - 如果读多写少,考虑
CopyOnWriteArrayList;如果需要强一致性+高频写,用ConcurrentLinkedQueue或分段加锁逻辑 -
Vector.size()和Vector.isEmpty()虽然同步,但拿到结果后状态可能已变 —— 别把它当“快照”用
替代 Vector 的现代写法(Java 5+)
Java 5 引入 java.util.concurrent 包后,Vector 就基本退出主力队列了。它既不是高性能容器,也不是真正实用的并发容器。
使用场景判断:
- 单线程:无条件选
ArrayList,内存和 CPU 都更省 - 简单同步需求:用
Collections.synchronizedList(new ArrayList()),比Vector更透明,也方便后期替换为其他并发实现 - 迭代中修改:必须用
Iterator.remove(),Vector的removeElementAt()是按索引删,容易越界或漏删
容易被忽略的一点:Vector 构造函数里传入的 capacityIncrement 参数,在 JDK 8+ 中已完全不生效 —— 扩容逻辑硬编码为翻倍,这个参数只是留着兼容旧序列化数据。










