JAVA源码学习之集合-Vector

前言

   前面讲到ArrayList和LinkList, LinkList在程序中虽然不常见,但是和和Vector相比的话,那使用率说也是必要高的, Vector工作这几年来,我完全没有使用过,开发或是研习大牛的代码时,也很少见。堪称隐士。下面就让我们一起研究下这位隐士的生活

正文

变量

    /**
     * 存储向量组件的数组缓冲区。 向量的容量是这个数组缓冲区的长度,并且至少足够包含向量的所有元 
     * 素。
     * Vector 中最后一个元素之后的任何数组元素都为空。
     */
    //Vector和ArrayList都是用数组作为数据结构的, 所以猜想,相关的add, remove等操作应该时一样的 
   //原理, 通过System.copyOf来实现
    protected Object[] elementData;

    
    protected int elementCount;

  
    /**
     * 向量容量自动增加的量。
     * 当它的大小变得大于它的容量时增加。 如果容量增量小于或等于零,容量
     *  每次需要增长时,向量的大小都会增加一倍。
     */
    protected int 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;
    }

    
    //指定数组的初始容量, 扩容向量默认为0,(当扩容向量为0时,那么每次扩容时,扩容的值一般是当 
    //前数组容量的2倍)
    public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }

    //默认初始容量是10
    public Vector() {
        this(10);
    }

    //初始容量为c的长度, 
    public Vector(Collection<? extends E> c) {
        Object[] a = c.toArray();
        elementCount = a.length;
        //如果是ArrayLsit, 因为都是数组,所以可以直接赋值
        if (c.getClass() == ArrayList.class) {
            elementData = a;
        } else { //使用arrays.copyOf来赋值
            elementData = Arrays.copyOf(a, elementCount, Object[].class);
        }
    }

添加

//使用了synchronized同步关键字
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;
        //和ArrayLsit的区别,如果capacityIncrement > 为 capacityIncrement ,否则
        //否则为oldCapacity增加当前的一倍
        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);
    }

 public synchronized void addElement(E obj) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = obj;
    }
//固定下标插入
public void add(int index, E element) {
        insertElementAt(element, index);
    }

 public synchronized void insertElementAt(E obj, int index) {
        modCount++;
        if (index > elementCount) {
            throw new ArrayIndexOutOfBoundsException(index
                                                     + " > " + elementCount);
        }
        ensureCapacityHelper(elementCount + 1);
        System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
        elementData[index] = obj;
        elementCount++;
    }

  //添加多个
  public synchronized boolean addAll(Collection<? extends E> c) {
        modCount++;
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityHelper(elementCount + numNew);
        System.arraycopy(a, 0, elementData, elementCount, numNew);
        elementCount += numNew;
        return numNew != 0;
    }
 //中间插入
 public synchronized boolean addAll(int index, Collection<? extends E> c) {
        modCount++;
        if (index < 0 || index > elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityHelper(elementCount + numNew);

        int numMoved = elementCount - index;
        if (numMoved > 0)
            System.arraycopy(elementData, index, elementData, index + numNew,
                             numMoved);

        System.arraycopy(a, 0, elementData, index, numNew);
        elementCount += numNew;
        return numNew != 0;
    }

通过添加,发现具体的实现原理和ArrayLsit是一样的,小区别就是扩容的增量。

最大的区别就是相关方法全部用synchronized关键字来修饰的,所以应该是线程安全的,但是性能就没有ArrayList好了, 为了验证自己的猜想,继续往下。

类的描述

发现自己好傻,我应该先看类的注释,和api文档的。这样去研究会更直观些,

Java 8 中文api文档

Vector类实现了一个可生长的数组对象。像一个数组,它包含的组件可以使用整数索引访问。然而, Vector的大小可以根据需要增长或缩小以适应添加和删除已经创建了 Vector后物品。 
每个向量试图优化维护capacity和capacityIncrement存储管理。capacity总是至少向量的大小一样大;它通常是更大,因为组件被添加到向量,向量的存储增加capacityIncrement大小的块。应用程序可以增加一个向量的能力之前插入大量的组件,这样可以减少增量重新分配的数量。

The iterators returned by this class's iterator和listIterator方法快速失败:如果向量结构修改创建迭代器后,任何时候以任何方式除非通过迭代器的remove或add方法,迭代器就会抛出一个ConcurrentModificationException。并发修改,因此,面对迭代器快速、清晰地失败,而不是冒着任意,不确定的行为在未来一个不确定的时间。返回的Enumerations elements方法不是很快失败。

注意,迭代器的快速失败行为不能得到保证,一般来说,不可能努力做出任何担保的存在不同步的并发修改。快速失败迭代器扔ConcurrentModificationException力所能及。因此,编写一个程序,这将是错误的依赖这个异常的正确性:迭代器的快速失败行为应该只用来检测错误。

Java 2平台v1.2,这个类实现List接口改造,使其 Java Collections Framework的一员。与新的集合实现,Vector是同步的。如果一个线程安全的实现不需要,建议使用ArrayList Vector。

看了Api文档的解释,充分的验证了上面的猜想,下一章的时候先看类的Api文档,在去验证

下面的相关的 remove等代码我就不一一例出来了,感兴趣的小伙伴可以去看源码,和ArrayLised的原理相同,只是加了synchronized关键字来修饰

上一章                                                                                                                                     下一章

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值