zoukankan      html  css  js  c++  java
  • Vector源码分析

    Vector与ArrayList底层实现基本类似,底层都是用数组实现的,最大的不同是Vector是线程安全的。ArrayList源码分析请参考ArrayList源码分析

    一、源码分析

    基于jdk1.7源码

    属性

        protected Object[] elementData;//用来存储元素
     
        protected int elementCount;//元素数量
     
        protected int capacityIncrement;//扩容增量,扩容时增加的容量大小。

    Vector多了一个capacityIncrement属性。当Vector需要扩容时,增加的容量大小就是该值。

    而ArrayList扩容时是扩充到原容量的1.5倍。

    构造器

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

    跟ArrayList一样,创建Vector时可以指定初始容量initalCapacity,如果不指定则默认初始容量为10

    Vector也可以在创建时指定扩容增量,如果不指定则为0。

    add方法

        public synchronized boolean add(E e) {
            modCount++;
            //确定是否还有容量
            ensureCapacityHelper(elementCount + 1);
            elementData[elementCount++] = e;
            return true;
        }

    实现与ArrayList差不多,最大区别是该方法进行了同步。继续往下跟代码。

        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;
            
            //扩容。指定了扩容增量,则增加该值。没指定,则扩容到原来的两倍
            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);
        }

    整个过程基本与ArrayList一样,但是不同点是Vecotor扩容增加的容量大小。

    如果Vector初始化时指定了扩容增量,则增加的容量值就是指定的扩容增量,否则,增加1倍容量,也就是扩容到原来的2倍。

    get方法

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

    很简单,与ArrayList一样,也是先进行边界检查,再根据下标获取元素。

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

    跟ArrayList实现差不多,不再赘述。

    二、Vector和ArrayList的比较

    1.扩容

    Vector在创建时能够指定扩容增量,如果指定了该增量,当自动扩容时增加的容量就是该增量值。如果创建时没指定增量(或该值<=0),则扩容1倍,即容量变为原来的2倍。

    ArrayList并没有提供能指定增量的构造方法,扩容0.5倍,即容量变为原来的1.5倍(具体参考ArrayList源码分析)

    2.线程安全和效率

    Vector的修改方法都是线程安全的,然而java.util.concurrent包中对容器提供了线程安全的实现版本,非线程安全时,可以用ArrayList来代替Vector,需要线程安全时可以使用Collections.synchronizedList(new ArrayList())和CopyOnWriteArrayList来替代,也就是说Vector被淘汰了。

    ArrayList并不是线程安全的,因此相对来说,ArrayList比Vector效率要高一些。

  • 相关阅读:
    Redis常用数据类型介绍、使用场景及其操作命令
    spring的官方文档地址
    ps基础学习笔记一
    类的加载时机与步骤(转)
    jvm的基本结构以及各部分详解(转)
    jdk1.8使用的url和driverName的改变
    测试框架简单了解
    shiro简单学习的简单总结
    easyui弹框后销毁当前tab弹框不显示的解决方式
    springboot学习章节代码-Spring MVC基础
  • 原文地址:https://www.cnblogs.com/rouqinglangzi/p/10115612.html
Copyright © 2011-2022 走看看