前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vector 源码解析

Vector 源码解析

原创
作者头像
HLee
修改2021-09-23 10:20:28
4310
修改2021-09-23 10:20:28
举报
文章被收录于专栏:房东的猫房东的猫

简介

Vector和ArrayList非常相似,它们都实现了相同的接口,继承相同的类,就连方法的实现也非常类似。和ArrayList不同的是,Vector是线程安全的,关键方法上都加了synchronized同步锁,由于Vector效率不高,所以使用的较少,要使用线程安全的ArrayList,推荐CopyOnWriteArrayList

类结构

Vector可以存放任意类型元素(包括null),允许重复,和ArrayList一致,内部采用Object类型数组存放数据,包含以下三个成员变量:

// Object数组,存放数据
protected Object[] elementData;

// 元素个数
protected int elementCount;

// 当数组容量不足时,容量增加capacityIncrement,如果capacityIncrement为0,则扩容为2倍
protected int capacityIncrement;

方法解析

Vector的方法都用synchronized关键字来确保线程安全,每次只有一个线程能访问此对象,在线程竞争激烈的情况下,这种方法效率非常低,所以实际并不推荐使用Vector。

构造函数

public Vector(Collection<? extends E> c) {
    elementData = c.toArray();
    elementCount = elementData.length;
    // c.toArray might (incorrectly) not return Object[] (see 6260652)
    if (elementData.getClass() != Object[].class)
       elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}

public Vector(int initialCapacity, int capacityIncrement) {
    super();
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    this.elementData = new Object[initialCapacity];
    this.capacityIncrement = capacityIncrement;
}

public Vector(int initialCapacity) {
    this(initialCapacity, 0);
}

public Vector() {
    this(10);
}

当我们调用new Vector()创建Vector集合时,直接创建了一个容量为10的Object数组(和ArrayList不同,ArrayList内部数组初始容量为0,只有在添加第一个元素的时候才扩容为10),并且capacityIncrement为0,意味着容量不足时,新数组容量为旧数组容量的2倍。

add(E e)

public synchronized boolean add(E e) {
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = e;
    return true;
}

private void ensureCapacityHelper(int minCapacity) {
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    // capacityIncrement为0的话,新容量为旧容量的2倍,不为0,则新容量为旧容量+capacityIncrement
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                     capacityIncrement : oldCapacity);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);
}

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}

添加逻辑和ArrayList的add方法大体一致,区别在于扩容策略有些不同,并且方法使用synchronized关键字修饰。

set(int index, E element)

public synchronized E set(int index, E element) {
    if (index >= elementCount)
        throw new ArrayIndexOutOfBoundsException(index);

    E oldValue = elementData(index);
    elementData[index] = element;
    return oldValue;
}

逻辑和ArrayList的set方法一致,方法使用synchronized关键字修饰。

get(int index)

public synchronized E get(int index) {
    if (index >= elementCount)
        throw new ArrayIndexOutOfBoundsException(index);

    return elementData(index);
}
E elementData(int index) {
    return (E) elementData[index];
}

逻辑和ArrayList的get方法一致,方法使用synchronized关键字修饰。

remove(int index)

public synchronized E remove(int index) {
    modCount++;
    if (index >= elementCount)
        throw new ArrayIndexOutOfBoundsException(index);
    E oldValue = elementData(index);

    int numMoved = elementCount - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--elementCount] = null; // Let gc do its work

    return oldValue;
}

逻辑和ArrayList的remove方法一致,方法使用synchronized关键字修饰。

trimToSize()

public synchronized void trimToSize() {
    modCount++;
    int oldCapacity = elementData.length;
    if (elementCount < oldCapacity) {
        elementData = Arrays.copyOf(elementData, elementCount);
    }
}

逻辑和ArrayList的trimToSize方法一致,方法使用synchronized关键字修饰。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 类结构
  • 方法解析
    • 构造函数
      • add(E e)
        • set(int index, E element)
          • get(int index)
            • remove(int index)
              • trimToSize()
              相关产品与服务
              对象存储
              对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档