java基础-Vector(向量)

Vector 是 Java 中一个经典的集合类,它是动态数组 的实现,位于 java.util 包中。虽然在现代 Java 开发中它已不是首选,但理解它的特性和历史背景仍然很重要。

Java的 Vector 类拥有一个清晰的继承与实现层次。它的完整声明如下:

java 复制代码
public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable

下面这个表格可以帮你快速了解 Vector 的整个"家谱"结构。

类别 类/接口 Vector 的关系 核心作用
父类 AbstractList 继承 提供了 List 接口的骨架实现,如 getaddremove 等方法的基本逻辑。
核心接口 List 实现 定义了有序集合(序列)的标准契约,是 Vector 作为动态数组的核心依据。
标记接口 RandomAccess 实现 标记接口 ,表明 Vector 支持高效(常数时间)的随机访问(如 get(i))。
Cloneable 实现 标记接口 ,表明 Vector 实例可以被 clone() 方法复制。
Serializable 实现 标记接口 ,表明 Vector 可以被序列化(可转化为字节流用于网络传输或持久化存储)。

整体架构图

Object 类开始的完整单继承链是:ObjectAbstractCollectionAbstractListVector

接口与实现的要点解析

了解这些接口和父类,能帮助你理解 Vector 的行为:

  • 线程安全的基石 :虽然线程安全不是通过某个特定接口定义的,但它是 Vector 区别于 ArrayList 最关键的实现细节。它的核心操作方法(如 add, remove, get)都使用 synchronized 关键字修饰,保证了多线程环境下的数据安全,但也带来了性能开销。

  • RandomAccess 的实际影响 :实现这个标记接口意味着像 Collections.binarySearch() 这样的算法在处理 Vector 时,会优先使用效率更高的基于索引的随机访问,而不是迭代器。

核心特性

1. 同步/线程安全

Vector 的所有主要方法都使用 synchronized 关键字修饰,因此是线程安全的。

java 复制代码
// 线程安全示例
Vector<String> vector = new Vector<>();
// 以下操作在多线程环境下是安全的
vector.add("Item1");
vector.get(0);

2. 动态扩容

当容量不足时,Vector 会自动增长:

  • 默认初始容量:10

  • 默认增长策略:容量翻倍(可自定义)

java 复制代码
Vector<Integer> v = new Vector<>(5, 3); // 初始容量5,每次增加3
for (int i = 0; i < 10; i++) {
    v.add(i);
    System.out.println("Size: " + v.size() + ", Capacity: " + v.capacity());
}

3. 遗留类

Vector 是 Java 1.0 就存在的类,后来为了更好的集合框架设计,在 Java 1.2 中引入了 Collection 框架。

与 ArrayList 的对比

特性 Vector ArrayList
线程安全 是(同步方法)
性能 较慢(同步开销) 较快
扩容策略 默认翻倍(可自定义增量) 默认增加50%
迭代器 fail-fast(快速失败) fail-fast
Java版本 1.0 1.2

基本用法示例

java 复制代码
import java.util.*;

public class VectorExample {
    public static void main(String[] args) {
        // 创建 Vector
        Vector<String> fruits = new Vector<>();
        
        // 添加元素
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.addElement("Cherry"); // 遗留方法
        
        // 获取元素
        System.out.println(fruits.get(0));      // Apple
        System.out.println(fruits.elementAt(1)); // 遗留方法: Banana
        
        // 遍历
        // 1. 使用迭代器
        Iterator<String> it = fruits.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        
        // 2. 使用 Enumeration(遗留方式)
        Enumeration<String> en = fruits.elements();
        while (en.hasMoreElements()) {
            System.out.println(en.nextElement());
        }
        
        // 容量相关操作
        System.out.println("Size: " + fruits.size());       // 当前元素数量
        System.out.println("Capacity: " + fruits.capacity()); // 当前容量
        
        fruits.ensureCapacity(20);  // 确保最小容量
        fruits.trimToSize();        // 将容量调整为当前大小
    }
}

线程安全示例

java 复制代码
import java.util.Vector;

public class ThreadSafeExample {
    private static Vector<Integer> vector = new Vector<>();
    
    public static void main(String[] args) throws InterruptedException {
        // 创建多个线程同时修改 Vector
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                vector.add(i);
            }
        });
        
        Thread t2 = new Thread(() -> {
            for (int i = 1000; i < 2000; i++) {
                vector.add(i);
            }
        });
        
        t1.start();
        t2.start();
        
        t1.join();
        t2.join();
        
        // 不会出现并发问题
        System.out.println("Vector size: " + vector.size()); // 应该是2000
    }
}

现代替代方案

1. 使用 ArrayList + 同步包装

java 复制代码
// 替代 Vector 的线程安全方案
List<String> syncList = Collections.synchronizedList(new ArrayList<>());

// 或者在并发场景下使用
List<String> concurrentList = new CopyOnWriteArrayList<>();

2. 并发集合类

java 复制代码
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ConcurrentLinkedQueue;

// 高并发读取场景
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();

// 并发队列
ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();

使用建议

使用 Vector 的场景

  1. 维护遗留代码

  2. 简单的多线程共享集合(但现代方案更好)

避免使用 Vector 的场景

  1. 新开发的项目

  2. 单线程环境(使用 ArrayList

  3. 高并发环境(使用 java.util.concurrent 包中的类)

重要方法总结

java 复制代码
// 添加元素
add(E e)             // 添加元素
addElement(E obj)    // 遗留方法
insertElementAt(E obj, int index)

// 获取元素
get(int index)
elementAt(int index) // 遗留方法
firstElement()
lastElement()

// 删除元素
remove(int index)
removeElement(Object obj)
clear()

// 容量管理
ensureCapacity(int minCapacity)
trimToSize()
setSize(int newSize)  // 可能填充null或截断

// 搜索
contains(Object o)
indexOf(Object o)

// 枚举器(遗留)
elements()  // 返回 Enumeration

性能考虑

由于 Vector 的方法都是同步的,在多线程竞争激烈的情况下,性能会受到影响。现代 Java 提供了更精细的并发控制机制:

java 复制代码
// 更好的多线程方案
List<String> list = new ArrayList<>();
// 只在必要时同步
synchronized(list) {
    list.add("item");
}

总结 :虽然 Vector 在 Java 历史上占有重要地位,但在现代开发中,ArrayListjava.util.concurrent 包中的并发集合通常是更好的选择。理解 Vector 有助于维护遗留代码,但在新项目中应优先考虑更现代的替代方案。

相关推荐
Knight_AL17 分钟前
设计模式之责任链模式:原理解析 + Java 示例
java·设计模式·责任链模式
1candobetter19 分钟前
JAVA后端开发——深入理解 Java Static
java·开发语言
一念一花一世界26 分钟前
PostIn项目实战 - 使用Mock数据尽早满足前后端接口开发需求
java·mock·postin·接口管理工具
白露与泡影28 分钟前
Spring事件机制完全指南:解耦利器与实战
java·后端·spring
DYS_房东的猫29 分钟前
《 C++ 零基础入门教程》第10章:C++20 核心特性 —— 编写更现代、更优雅的 C++
java·c++·c++20
好好沉淀29 分钟前
Spring AI Alibaba
java·人工智能·spring
BD_Marathon42 分钟前
MyBatis各种查询功能
java·开发语言·mybatis
雪人.1 小时前
Spring常见面试题(2026版30道面试题)
java·后端·spring
温暖小土1 小时前
深入理解 Spring Boot 配置加载顺序:外部化配置的艺术
java·springboot
小林rr1 小时前
深入探索 C++:现代特性、工程实践与性能优化全解
java·c++·性能优化