java学习--Vector

一、什么是 Vector

Vectorjava.util 包下的老牌类(JDK1.0 就存在),同样实现了 List 接口,本质也是动态扩容的数组,核心区别是:

  • 所有核心方法(如 addremoveget)都加了 synchronized 关键字,是线程安全的。
  • 底层基于数组实现,特性和 ArrayList 类似(有序、可重复、允许 null),但性能比 ArrayList 低。

二、核心用法(完整示例代码)

Vector 的 API 和 ArrayList 高度兼容,用法几乎一致,代码可直接运行:

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

public class VectorDemo {
    public static void main(String[] args) {
        // 1. 创建 Vector 对象(指定泛型,避免类型转换)
        // 方式1:默认初始化,初始容量10
        Vector<String> vector = new Vector<>();
        // 方式2:指定初始容量(推荐,减少扩容)
        // Vector<String> vector = new Vector<>(20);
        // 方式3:指定初始容量 + 扩容增量
        // Vector<String> vector = new Vector<>(10, 5); // 满了之后每次扩容5个位置

        // 2. 添加元素
        vector.add("Java");       // 末尾添加
        vector.add("Python");
        vector.add(1, "C++");     // 指定索引添加,元素后移
        System.out.println("添加后:" + vector); // 输出:[Java, C++, Python]

        // 3. 获取元素
        String first = vector.get(0);
        System.out.println("第一个元素:" + first); // 输出:Java

        // 4. 修改元素
        vector.set(2, "Go");
        System.out.println("修改后:" + vector); // 输出:[Java, C++, Go]

        // 5. 删除元素
        vector.remove(1);    // 按索引删除
        vector.remove("Go"); // 按元素值删除
        System.out.println("删除后:" + vector); // 输出:[Java]

        // 6. 遍历元素(和 ArrayList 一致)
        // 方式1:普通for循环
        System.out.println("普通for循环遍历:");
        for (int i = 0; i < vector.size(); i++) {
            System.out.println(vector.get(i));
        }

        // 方式2:增强for循环
        System.out.println("增强for循环遍历:");
        for (String s : vector) {
            System.out.println(s);
        }

        // 方式3:迭代器
        System.out.println("迭代器遍历:");
        Iterator<String> it = vector.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }

        // 7. 其他常用方法
        int size = vector.size(); // 获取元素个数
        boolean isEmpty = vector.isEmpty(); // 判断是否为空
        boolean contains = vector.contains("Java"); // 判断是否包含元素
        vector.clear(); // 清空所有元素
    }
}

三、关键特性解析

1. 扩容机制(和 ArrayList 不同)
  • 默认初始容量:10。
  • 扩容规则(核心区别):
    • 如果创建时未指定扩容增量:扩容后容量 = 原容量 × 2(比如 10→20→40);
    • 如果创建时指定了扩容增量 (如 new Vector(10,5)):扩容后容量 = 原容量 + 增量(10→15→20)。
  • 对比:ArrayList 扩容是原容量的 1.5 倍,Vector 扩容幅度更大,更易浪费内存。
2. 线程安全的实现方式

Vector 的线程安全是通过给核心方法加 synchronized 关键字实现的,比如:

复制代码
// Vector 的 add 方法源码(简化版)
public synchronized boolean add(E e) {
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = e;
    return true;
}

这种方式虽然保证了线程安全,但性能损耗大(每次调用方法都要加锁),高并发场景下效率很低。

3. 迭代器特性

Vector 除了普通的 Iterator,还提供了专属的 Enumeration(枚举),用法和迭代器类似,但功能更简单(仅支持遍历,不支持删除):

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

public class VectorEnumeration {
    public static void main(String[] args) {
        Vector<String> vector = new Vector<>();
        vector.add("a");
        vector.add("b");
        
        // 使用 Enumeration 遍历
        Enumeration<String> en = vector.elements();
        while (en.hasMoreElements()) {
            System.out.println(en.nextElement());
        }
    }
}

四、Vector vs ArrayList(核心对比)

这是最常考的知识点,用表格清晰对比:

特性 Vector ArrayList
线程安全 线程安全(方法加 synchronized) 非线程安全
扩容规则 默认扩容 2 倍(可指定增量) 默认扩容 1.5 倍
性能 低(锁开销) 高(无锁)
迭代器 / 枚举 支持 Iterator + Enumeration 仅支持 Iterator
诞生版本 JDK1.0(古老) JDK1.2(集合框架统一规范)
适用场景 低并发的线程安全场景 单线程 / 无并发读写场景

五、使用建议(避坑指南)

  1. 不推荐优先使用 Vector :即使需要线程安全的 List,也不建议用 Vector,因为它的锁粒度太大(整个方法加锁),性能差。替代方案:
    • 低并发:Collections.synchronizedList(new ArrayList<>())(给 ArrayList 加全局锁);
    • 高并发读、低并发写:CopyOnWriteArrayList(写时复制,读无锁,性能远高于 Vector)。
  2. 扩容增量优化 :如果必须用 Vector,建议创建时指定初始容量和扩容增量,避免频繁扩容和内存浪费。
  3. 遍历删除注意 :和 ArrayList 一样,增强 for 循环中直接删除会抛 ConcurrentModificationException,需用迭代器的 it.remove()

总结

  1. Vector 是线程安全的动态数组,通过 synchronized 关键字实现,但性能低于 ArrayList,扩容默认 2 倍(可指定增量)。
  2. VectorArrayList 核心 API 兼容,但诞生更早、性能更差,仅适用于低并发的线程安全场景。
  3. 线程安全的 List 优先选择 CopyOnWriteArrayList(高并发)或 Collections.synchronizedList(低并发),而非 Vector
相关推荐
sheji34162 小时前
【开题答辩全过程】以 基于Java的校内美食推荐系统的设计与实现为例,包含答辩的问题和答案
java·开发语言·美食
白典典2 小时前
解决iTextPDF生成手册时目录页码与实际页码不匹配问题
java·spring·intellij-idea
静心观复2 小时前
foreach中使用remove踩坑
java
内存不泄露2 小时前
基于 Spring Boot 的医院预约挂号系统(全端协同)设计与实现
java·vue.js·spring boot·python·flask
_叶小格_2 小时前
ansible自动化入门基础
运维·笔记·学习·自动化·ansible
袁慎建@ThoughtWorks2 小时前
如何发布自定义 Spring Boot Starter
java·spring boot·后端
im_AMBER2 小时前
前端 + agent 开发学习路线
前端·学习·agent
开开心心_Every2 小时前
强制打字练习工具:打够百字才可退出
java·游戏·微信·eclipse·pdf·excel·语音识别
xiaolyuh1232 小时前
Redis 核心业务流程
java·redis·spring