ArrayLsit与Vector的区别

ArrayList 和 Vector 类都是基于数组实现的 List 类. ArrayList 和 Vector 封装了一个动态的, 允许再分配的 Object[] 数组. ArrayList 和 Vector 使用 initialCapacity 参数来设置该数组的长度. 当向 ArrayLsit 和 Vector 数组中添加元素超过改数组的长度时, 在底层会自动将数组进行扩容.

关于 ArrayList 和 Vector 的区别, 主要有这几点:

(1) ArrayList 是线程不安全的, 当多个线程访问同一个ArrayList 集合, 如果有超过一个线程修改了 ArrayList 集合, 则程序必须手动保证该集合的同步性.  Vector是线程安全的, Vector 类中的方法都有 synchronized 修饰, 所以 Vector 性能比 ArrayLsit 性能要差.

Vector 类的所有方法都是同步的, 可以由多个线程安全地访问一个 Vector 对象. 但是在一个线程访问 Vector 的话代码要在同步操作上耗费大量的时间.  ArrayList 不是同步的, 所以在不需要保证线程安全时建议使用 ArrayLsit.

(2) ArrayList 和 Vector 底层都是采用数组来存储元素的, 当数组存储空间不够时, 两个类对数组扩容的方式是不一样的.

ArrayLsit 扩容机制与初始化数组容量为10 的分析见https://blog.csdn.net/huhahuha_/article/details/84329524

(3)通过 Vector 的构造参数可以设置增量因子, 用于对Vector 底层数组的扩容. 分析见 Vector 源码:

     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;
     }
     
     
     public Vector(int initialCapacity) {
            this(initialCapacity, 0);
        }
     
        /**
         * Constructs an empty vector so that its internal data array
         * has size {@code 10} and its standard capacity increment is
         * zero.
         */
        public Vector() {
            this(10);
        }

从上面 Vector 的源代码中可以看出, Vector 中多了一个构造方法,  Vector(int initialCapacity, int  capacityIncrement).

capacityIncrement 就是增量因子,如果设置增量因子, 这个 capacityIncrement 会用于对数组进行扩容.

当调用 Vector 无参构造时,  java 默认初始化 initialCapacity 值为 10. 并且设置 capacityIncrement 为0.

当采用无参构造创建ArrayList 和 Vector 对象时, Vector 和 ArrayList 的默认初始化长度都为10. 只不过 ArrayList 是第一次调用 add() 方法时将 elementData 数组扩容为10, 而 Vector 是初始化时就将 elementData 数组设置为10.

下面来分析 Vector 的 add() 方法, 看看 Vector 是如何实现对数组的扩容;

elementCount 是记录当前数组元素的个数. 也就是记录 Vector 集合中元素的个数. 初始化值为0.

下面来看看 ensureCapacityHelper() 方法:

    private void ensureCapacityHelper(int minCapacity) {
            // overflow-conscious code
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
     
        /**
         * The maximum size of array to allocate.
         * Some VMs reserve some header words in an array.
         * Attempts to allocate larger arrays may result in
         * OutOfMemoryError: Requested array size exceeds VM limit
         */
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
     
        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);
        }

ensureCapacityHelper() 方法首先会判断 所需容量是否大于当前 elementData数组的长度,  如果所需容量大于 数组容量, 则调用 grow() 方法对数组进行扩容.

通过上面 grow() 方法的代码, 可以看到 capacityIncrement 的作用了, 当 capacityIncrement 的值大于0时, 一般也就是也就是我们创建Vector 对象时调用有参构造设置了 capacityIncrement 的值, 数组扩容的长度为 当前数组长度加上 capacityIncrement.  

当 capacityIncrement 值为0 时(采用默认构造方法), 数组扩容为当前数组容量的 2倍.  最后使用 Arrays.copyOf() 方法对数组进行扩容.  可以看出 ArrayLsit 和 Vector 的扩容机制的不同.
---------------------
作者:huhahuha_
来源:CSDN
原文:https://blog.csdn.net/huhahuha_/article/details/84340391
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2019-06-25 17:20  天涯海角路  阅读(192)  评论(0)    收藏  举报