java集合之Vector

Vector和前面讲的Arraylist很相似,也是一个保存数据的集合,下面我们来看看Vector的源码。和ArrayList最大区别是,它是一个线程安全的集合,所有方法都加了synchronized,效率相对来说要低一点,另外,有一个增量系数,如果指定,那么每次都会增加一个系数的大小,否则就扩大一倍。
在这里插入图片描述

1、重要属性
	/**
     * 存储元素所使用的数组
     */
	protected Object[] elementData;
	/**
     * 数组中已经存放的元素个数
     */
    protected int elementCount;
    /**
     * 容量增加系数,就是扩容的时候增加的容量
     */
    protected int capacityIncrement;
2、构造器
 	/**
     * 带参构造函数
     * initialCapacity 初始容量
     * capacityIncrement 扩容系数
     */
	public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
           // 初始化数组
        this.elementData = new Object[initialCapacity];
        // 将扩容系数赋值
        this.capacityIncrement = capacityIncrement;
    }
   /**
     * 带参构造函数
     * initialCapacity 初始容量
     */
    public Vector(int initialCapacity) {
        // 调用上一个构造函数,扩容系数为0
        this(initialCapacity, 0);
    }

   	/**
     * 无参构造函数,初始容量默认为10
     */
    public Vector() {
        this(10);
    }

   /**
    * 将Collection对象转换成数组,然后将数组的地址赋值给elementData。
	* 执行Arrays.copy方法,把Collection对象的内容copy到elementData中
   	*/
    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);
    }
3、添加元素以及怎么扩容

我们以添加单个元素为例,添加集合或者在指定位置添加元素,大同小异

/**
* e 需要添加进数组的元素
*/
public synchronized boolean add(E e) {
  	modCount++;
  	// 扩容 添加第一个元素elementCount 为0
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = e;
    return true;
}
/**
* minCapacity 最小容量,添加第一个元素是为1
*/
private void ensureCapacityHelper(int minCapacity) {
    // overflow-conscious code
    // 当最小容量 - 数组长度 得到的值大于0,就该扩容了,比如:添加到第十一个元素的时候,
    // minCapacity = 11,elementData.length = 10,说明数组已经满了,这也说明数组不满的时候,
    // 是不会进行扩容的
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
/**
* 数组最大容量
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* 对数组进行扩容 
*/
private void grow(int minCapacity) {
    // overflow-conscious code
    // 旧的数组容量
    int oldCapacity = elementData.length;
    // 计算新的容量,capacityIncrement 这个值代表每次扩容的时候扩多少,如果初始化的时候传了值,
    // 那么就取这个值,如果没传,则取oldCapacity,也就是旧容量的1倍
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                     capacityIncrement : oldCapacity);
    // 以下两个if是为健壮性考虑,正常情况是不会走进去的
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // 将旧数组的内容拷贝到新数组,并将新数组地址赋值给elementData  至此扩容完成
    elementData = Arrays.copyOf(elementData, newCapacity);
}
4、删除元素

Vector的批量删除与Arraylist有区别,它是通过迭代器去实现的

/**
* 批量删除
*/
public synchronized boolean removeAll(Collection<?> c) {
	// 调用父类的removeAll
    return super.removeAll(c);
}

/**
* AbstractCollection的removeAll
*/
public boolean removeAll(Collection<?> c) {
    Objects.requireNonNull(c);
    boolean modified = false;
    // iterator会调用到Vector的内部Itr
    Iterator<?> it = iterator();
    // 通过hasNext判断是否还有下一个元素
    // 通过next获取下一个元素,并对cursor、lastRet进行赋值
    // 通过contains得到集合是否包含该元素
    // 如果包含,则调用迭代器的remove
    while (it.hasNext()) {
        if (c.contains(it.next())) {
            it.remove();
            modified = true;
        }
    }
    return modified;
}

/**
* Vector的内部类Itr的方法,判断集合中是否还有下一个元素
*/
public boolean hasNext() {
    // Racy but within spec, since modifications are checked
    // within or after synchronization in next/previous
    return cursor != elementCount;
}

/**
* Vector的内部类Itr的方法,从集合中获取下一个元素
* cursor 初始值为0 ,每一次调用next(),cursor+1
* 通过cursor、lastRet的转换,获取对应索引下的值
*/
public E next() {
    synchronized (Vector.this) {
        checkForComodification();
        int i = cursor;
        if (i >= elementCount)
            throw new NoSuchElementException();
        cursor = i + 1;
        return elementData(lastRet = i);
    }
}

/**
* Vector的内部类Itr的方法,删除元素
* 因为通过it.next()已经对lastRet进行了赋值,所以真正删除元素的时候调用的是Vector.this.remove(lastRet);
*/
public void remove() {
    if (lastRet == -1)
        throw new IllegalStateException();
    synchronized (Vector.this) {
        checkForComodification();
        Vector.this.remove(lastRet);
        expectedModCount = modCount;
    }
    cursor = lastRet;
    lastRet = -1;
}

/**
* Vector的remove方法 最终删除元素的方法
*/
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;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值