一、Vector集合概述
1.1 Vector的历史地位
Vector是Java集合框架中的元老级类,自JDK 1.0就已存在。它是早期Java版本中重要的动态数组实现,虽然现在已不推荐在新项目中使用,但理解其特性对于掌握Java集合框架的演进历程具有重要意义。
1.2 Vector的核心定位
Vector是一个线程安全的动态数组实现,它通过在方法级别添加synchronized关键字来保证多线程环境下的数据安全。
二、Vector集合核心特点
2.1 数据结构特性
- 底层结构:基于动态数组实现
- 索引访问:支持通过索引直接访问元素
- 性能特征:查询速度快,增删操作相对较慢
- 线程安全:所有公共方法都是同步的
2.2 与ArrayList的对比
|------|------------|-----------|
| 特性 | Vector | ArrayList |
| 线程安全 | 是(同步方法) | 否 |
| 性能 | 相对较低(同步开销) | 相对较高 |
| 扩容策略 | 默认2倍增长 | 默认1.5倍增长 |
| 历史版本 | JDK 1.0 | JDK 1.2 |
| 推荐使用 | 不推荐 | 推荐 |
三、Vector集合实战详解
3.1 创建Vector实例
java
import java.util.Vector;
public class VectorCreation {
public static void main(String[] args) {
System.out.println("=== Vector创建方式演示 ===");
// 1. 创建空的Vector(默认容量10)
Vector<String> vector1 = new Vector<>();
System.out.println("空Vector容量: " + vector1.capacity());
// 2. 创建指定初始容量的Vector
Vector<Integer> vector2 = new Vector<>(15);
System.out.println("指定容量Vector: " + vector2.capacity());
// 3. 创建指定初始容量和容量增量的Vector
Vector<Double> vector3 = new Vector<>(10, 5);
System.out.println("带增量Vector初始容量: " + vector3.capacity());
// 添加元素测试扩容
for (int i = 0; i < 12; i++) {
vector3.add(i * 1.0);
}
System.out.println("扩容后容量: " + vector3.capacity());
}
}
3.2 元素添加操作
java
public class VectorAddOperations {
public static void main(String[] args) {
Vector<String> vector = new Vector<>();
System.out.println("=== Vector添加操作演示 ===");
// 基本添加方法
vector.add("Apple");
vector.add("Banana");
// Vector特有的添加方法
vector.addElement("Cherry");
vector.addElement("Orange");
System.out.println("添加后Vector: " + vector);
// 指定位置插入
vector.add(1, "Blueberry");
System.out.println("指定位置插入后: " + vector);
// 批量添加
Vector<String> fruits = new Vector<>();
fruits.add("Grape");
fruits.add("Mango");
vector.addAll(fruits);
System.out.println("批量添加后: " + vector);
}
}
3.3 元素访问操作
java
public class VectorAccessOperations {
public static void main(String[] args) {
Vector<String> vector = new Vector<>();
vector.add("Apple");
vector.add("Banana");
vector.add("Cherry");
vector.add("Orange");
System.out.println("=== Vector访问操作演示 ===");
// 通过索引访问
String fruit1 = vector.get(1);
System.out.println("索引1的元素: " + fruit1);
// Vector特有的访问方法
String fruit2 = vector.elementAt(2);
System.out.println("elementAt(2): " + fruit2);
// 获取首尾元素
String first = vector.firstElement();
String last = vector.lastElement();
System.out.println("首元素: " + first + ", 尾元素: " + last);
// 获取子列表
List<String> subList = vector.subList(1, 3);
System.out.println("子列表: " + subList);
}
}
3.4 元素修改操作
java
public class VectorUpdateOperations {
public static void main(String[] args) {
Vector<String> vector = new Vector<>();
vector.add("Apple");
vector.add("Banana");
vector.add("Cherry");
System.out.println("=== Vector修改操作演示 ===");
System.out.println("修改前: " + vector);
// 修改指定位置元素
String oldValue = vector.set(1, "Blueberry");
System.out.println("被替换的值: " + oldValue);
System.out.println("修改后: " + vector);
// 使用setElementAt方法
vector.setElementAt("Strawberry", 2);
System.out.println("setElementAt后: " + vector);
}
}
3.5 元素删除操作
java
public class VectorRemoveOperations {
public static void main(String[] args) {
Vector<String> vector = new Vector<>();
vector.add("Apple");
vector.add("Banana");
vector.add("Cherry");
vector.add("Orange");
vector.add("Banana"); // 重复元素
System.out.println("=== Vector删除操作演示 ===");
System.out.println("初始Vector: " + vector);
// 按索引删除
String removed1 = vector.remove(1);
System.out.println("删除索引1的元素: " + removed1);
System.out.println("删除后: " + vector);
// 按元素值删除(首次出现)
boolean removed2 = vector.remove("Banana");
System.out.println("按值删除是否成功: " + removed2);
System.out.println("删除后: " + vector);
// Vector特有的删除方法
vector.removeElement("Orange");
System.out.println("removeElement后: " + vector);
// 删除所有元素
vector.clear();
System.out.println("clear后: " + vector);
System.out.println("是否为空: " + vector.isEmpty());
}
}
3.6 容量与大小管理
java
public class VectorCapacityManagement {
public static void main(String[] args) {
Vector<Integer> vector = new Vector<>(5, 3);
System.out.println("=== Vector容量管理演示 ===");
// 初始状态
System.out.println("初始容量: " + vector.capacity());
System.out.println("初始大小: " + vector.size());
System.out.println("是否为空: " + vector.isEmpty());
// 添加元素
for (int i = 1; i <= 7; i++) {
vector.add(i);
}
System.out.println("添加7个元素后:");
System.out.println("容量: " + vector.capacity()); // 扩容后的容量
System.out.println("大小: " + vector.size());
// 容量调整
vector.trimToSize();
System.out.println("trimToSize后容量: " + vector.capacity());
// 确保容量
vector.ensureCapacity(20);
System.out.println("ensureCapacity(20)后容量: " + vector.capacity());
}
}
3.7 多种遍历方式
java
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
public class VectorTraversal {
public static void main(String[] args) {
Vector<String> vector = new Vector<>();
vector.add("Apple");
vector.add("Banana");
vector.add("Cherry");
vector.add("Orange");
System.out.println("=== Vector遍历方式演示 ===");
// 1. 传统for循环
System.out.println("1. 传统for循环:");
for (int i = 0; i < vector.size(); i++) {
System.out.println("索引 " + i + ": " + vector.get(i));
}
// 2. 增强for循环
System.out.println("\n2. 增强for循环:");
for (String fruit : vector) {
System.out.println("元素: " + fruit);
}
// 3. 迭代器遍历
System.out.println("\n3. 迭代器遍历:");
Iterator<String> iterator = vector.iterator();
while (iterator.hasNext()) {
System.out.println("元素: " + iterator.next());
}
// 4. Vector特有的Enumeration遍历
System.out.println("\n4. Enumeration遍历:");
Enumeration<String> enumeration = vector.elements();
while (enumeration.hasMoreElements()) {
System.out.println("元素: " + enumeration.nextElement());
}
// 5. forEach方法(Java 8+)
System.out.println("\n5. forEach方法:");
vector.forEach(fruit -> System.out.println("元素: " + fruit));
}
}
3.8 搜索与检查操作
java
public class VectorSearchOperations {
public static void main(String[] args) {
Vector<String> vector = new Vector<>();
vector.add("Apple");
vector.add("Banana");
vector.add("Cherry");
vector.add("Banana");
vector.add("Orange");
System.out.println("=== Vector搜索操作演示 ===");
// 元素存在性检查
boolean containsApple = vector.contains("Apple");
System.out.println("是否包含Apple: " + containsApple);
// 查找元素索引
int firstIndex = vector.indexOf("Banana");
int lastIndex = vector.lastIndexOf("Banana");
System.out.println("Banana第一次出现位置: " + firstIndex);
System.out.println("Banana最后一次出现位置: " + lastIndex);
// 从指定位置开始搜索
int indexFrom = vector.indexOf("Banana", 2);
System.out.println("从位置2开始搜索Banana: " + indexFrom);
// 检查包含所有元素
Vector<String> checkList = new Vector<>();
checkList.add("Apple");
checkList.add("Cherry");
boolean containsAll = vector.containsAll(checkList);
System.out.println("是否包含所有检查元素: " + containsAll);
}
}
3.9 数组转换操作
java
public class VectorArrayConversion {
public static void main(String[] args) {
Vector<String> vector = new Vector<>();
vector.add("Apple");
vector.add("Banana");
vector.add("Cherry");
System.out.println("=== Vector数组转换演示 ===");
// 转换为Object数组
Object[] objectArray = vector.toArray();
System.out.println("Object数组:");
for (Object obj : objectArray) {
System.out.println(obj);
}
// 转换为指定类型数组
String[] stringArray = vector.toArray(new String[0]);
System.out.println("String数组:");
for (String str : stringArray) {
System.out.println(str);
}
// 使用指定大小的数组
String[] sizedArray = vector.toArray(new String[vector.size()]);
System.out.println("指定大小数组长度: " + sizedArray.length);
}
}
3.10 线程安全演示
java
public class VectorThreadSafety {
public static void main(String[] args) throws InterruptedException {
System.out.println("=== Vector线程安全演示 ===");
Vector<Integer> sharedVector = new Vector<>();
// 创建任务:向Vector中添加元素
Runnable addTask = () -> {
String threadName = Thread.currentThread().getName();
for (int i = 0; i < 50; i++) {
sharedVector.add(i);
System.out.println(threadName + " 添加: " + i);
try {
Thread.sleep(10); // 模拟处理时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
// 创建多个线程同时操作Vector
Thread thread1 = new Thread(addTask, "线程-1");
Thread thread2 = new Thread(addTask, "线程-2");
Thread thread3 = new Thread(addTask, "线程-3");
thread1.start();
thread2.start();
thread3.start();
// 等待所有线程完成
thread1.join();
thread2.join();
thread3.join();
System.out.println("最终Vector大小: " + sharedVector.size());
System.out.println("预期大小: 150, 实际大小: " + sharedVector.size());
System.out.println("数据一致性: " + (sharedVector.size() == 150));
}
}
四、List集合总结
4.1 List接口核心特性
有序性保证
- 严格保持元素的插入顺序
- 每个元素有确定的索引位置(0-based)
元素可重复性 - 允许存储重复元素
- 通过equals()方法判断元素相等性
索引操作支持 - 支持通过索引直接访问、插入、删除元素
- 提供丰富的基于索引的操作方法
4.2 三大List实现类对比
|------|-----------|------------|--------|
| 特性 | ArrayList | LinkedList | Vector |
| 底层结构 | 动态数组 | 双向链表 | 动态数组 |
| 线程安全 | 否 | 否 | 是 |
| 查询性能 | O(1) | O(n) | O(1) |
| 增删性能 | O(n) | O(1) | O(n) |
| 内存占用 | 较小 | 较大 | 较小 |
| 扩容策略 | 1.5倍 | 无 | 2倍 |
| 推荐使用 | 推荐 | 特定场景 | 不推荐 |
4.3 选择指南
选择ArrayList:
- 大部分操作是查询
- 单线程环境
- 内存使用敏感的场景
选择LinkedList: - 频繁在头部插入删除
- 需要实现队列或栈
- 元素数量变化大
选择Vector: - 遗留系统维护
- 简单的多线程场景
- 不需要高性能要求的线程安全
4.4 最佳实践建议
- 优先使用ArrayList:在大多数场景下是最佳选择
- 线程安全方案:使用Collections.synchronizedList()包装ArrayList
- 容量规划:预先估算数据量,设置合适的初始容量
- 遍历选择:根据具体需求选择合适的遍历方式
- 泛型使用:始终使用泛型保证类型安全
总结
Vector作为Java集合框架的历史遗留类,虽然在新项目中不推荐使用,但理解其特性和实现原理对于深入掌握Java集合框架具有重要意义。通过本文的详细解析,读者应该能够全面理解Vector的工作原理、使用方法以及与其他List实现类的区别,从而在实际开发中做出更加明智的技术选型。
在大多数现代Java应用中,ArrayList配合适当的同步机制通常是更好的选择。