Java Vector集合全面解析:线程安全的动态数组

一、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 最佳实践建议

  1. 优先使用ArrayList:在大多数场景下是最佳选择
  2. 线程安全方案:使用Collections.synchronizedList()包装ArrayList
  3. 容量规划:预先估算数据量,设置合适的初始容量
  4. 遍历选择:根据具体需求选择合适的遍历方式
  5. 泛型使用:始终使用泛型保证类型安全

总结

Vector作为Java集合框架的历史遗留类,虽然在新项目中不推荐使用,但理解其特性和实现原理对于深入掌握Java集合框架具有重要意义。通过本文的详细解析,读者应该能够全面理解Vector的工作原理、使用方法以及与其他List实现类的区别,从而在实际开发中做出更加明智的技术选型。
在大多数现代Java应用中,ArrayList配合适当的同步机制通常是更好的选择。

相关推荐
毕设源码-朱学姐3 小时前
【开题答辩全过程】以 广州网红点打卡介绍网站为例,包含答辩的问题和答案
java·eclipse
程序定小飞3 小时前
基于springboot的web的音乐网站开发与设计
java·前端·数据库·vue.js·spring boot·后端·spring
Hello_WOAIAI3 小时前
2.4 python装饰器在 Web 框架和测试中的实战应用
开发语言·前端·python
搬山.摧城4 小时前
线程池和单例模式
开发语言·单例模式
百锦再4 小时前
第1章 Rust语言概述
java·开发语言·人工智能·python·rust·go·1024程序员节
武昌库里写JAVA4 小时前
element-ui 2.x 及 vxe-table 2.x 使用 css 定制主题
java·vue.js·spring boot·sql·学习
一叶之秋14124 小时前
QT背景介绍与环境搭建
开发语言·qt
java1234_小锋4 小时前
PyTorch2 Python深度学习 - 模型保存与加载
开发语言·python·深度学习·pytorch2
JavaGuide4 小时前
OPPO 后端校招面试,过于简单了!
java·后端