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 有助于维护遗留代码,但在新项目中应优先考虑更现代的替代方案。

相关推荐
光头程序员1 小时前
学习笔记——常识解答之垃圾回收机制
java·笔记·学习
渡我白衣1 小时前
并行的野心与现实——彻底拆解 C++ 标准并行算法(<execution>)的模型、陷阱与性能真相
java·开发语言·网络·c++·人工智能·windows·vscode
czlczl200209251 小时前
SpringBoot中web请求路径匹配的两种风格
java·前端·spring boot
bill4471 小时前
BPMN2.0,flowable工作流指向多节点,并且只能选择其中一个节点的处理方式
java·工作流引擎·bpmn
2022.11.7始学前端1 小时前
n8n第四节 表单触发器:让问卷提交自动触发企微消息推送
java·前端·数据库·n8n
Catcharlotte1 小时前
异常(3)
java
岁岁种桃花儿1 小时前
Java应用篇如何基于Redis共享Session实现短信登录
java·开发语言
资深低代码开发平台专家1 小时前
通用编程时代正在向专用化分层演进
java·大数据·c语言·c++·python
开心香辣派小星1 小时前
23种设计模式-17备忘录模式
java·设计模式·备忘录模式