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实例

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 元素添加操作

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 元素访问操作

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 元素修改操作

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 元素删除操作

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 容量与大小管理

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 多种遍历方式

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 搜索与检查操作

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 数组转换操作

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 线程安全演示

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配合适当的同步机制通常是更好的选择。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值