List集合之Vector

19 篇文章 1 订阅

Vector

相比很多同学在刚接触 Java 集合的时候,线程安全的 List 用的一定是 Vector。但是现在用到的线程安全的 List 一般都会用 CopyOnWriteArrayList,很少有人再去用 Vector 了,至于为什么,文章中会具体说到。接下来,我们先来简单分析一下 Vector 的源码

Vector 源码

VectorArrayList 的底层实现是一样的,都是由数组实现的

Vector 变量

public class Vector<E> extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
     
    // 存放元素的数组 
    protected Object[] elementData;
    
    // 元素个数
    protected int elementCount;
    
    // 扩容自增容量大小
    protected int capacityIncrement;
}        

Vector 的初始化

// 无参构造器
public Vector() {
    this(10);
}

// 指定初始化容量的构造器
public Vector(int initialCapacity) {
    this(initialCapacity, 0);
}

// 指定初始化容量和扩容容量大小的构造器
public Vector(int initialCapacity, int capacityIncrement) {
    super();
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
    this.elementData = new Object[initialCapacity];
    this.capacityIncrement = capacityIncrement;
}

从上面的构造器中可以看出,如果调用无参构造器,则会创建一个初始化容量为 10,扩容容量为 0Vector 集合

Vectoradd() 方法

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

public synchronized void addElement(E obj) {
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = obj;
}

VectorremoveElement() 方法

public synchronized boolean removeElement(Object obj) {
    modCount++;
    int i = indexOf(obj);
    if (i >= 0) {
        removeElementAt(i);
        return true;
    }
    return false;
}

public synchronized void removeAllElements() {
    modCount++;
    for (int i = 0; i < elementCount; i++)
        elementData[i] = null;
    elementCount = 0;
}

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;
}

Vectorget() 方法

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

Vectorset() 方法

public synchronized E set(int index, E element) {
    if (index >= elementCount)
        throw new ArrayIndexOutOfBoundsException(index);
    E oldValue = elementData(index);
    elementData[index] = element;
    return oldValue;
}

Vector 的扩容

Vector 的扩容机制和 ArrayList 的很像

private void grow(int minCapacity) {
    // 初始化数组的长度,默认为 10
    int oldCapacity = elementData.length;
    // 是否指定扩容容量,不指定扩容为原来的2倍
    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);
}

通过上面的方法,我们可以看出,

  • 如果指定了扩容容量的大小,则扩容的新数组大小为:原来的数组加上扩容容量的大小
  • 如果不指定扩容容量的大小,则扩容的新数组大小为:原来数组大小的 2

这样扩容为原来的 2 倍是很消耗空间的,这也是 Vector 被弃用的原因之一

Vector 小结

  • Vector 是线程安全的 List,底层是数组实现的
  • Vector 的每个方法都进行了加锁,数据操作效率低下
  • Vector 每次扩容的大小都是原来数组大小的 2
  • Vector 实现了 RandomAccess 接口,支持随机读取,因此更加推荐使用 for 循环进行遍历
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值