ArrayList和Vector的区别

ArrayList和Vector都是集合,允许重复的key,允许null key
查看源码发现,ArrayList和Vector都继承了AbastractList抽象类,实现类List接口(List接口继承了Collection接口)、RandomAccess接口、Cloneable接口、Serializable接口


public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable

然后通过一段代码执行来查看源码来分析两者之间的不同点

      ArrayList<Integer> integers=new ArrayList<Integer>(10);
        integers.add(2);
        integers.add(1);
        integers.add(null);
        integers.add(null);
        integers.remove(1);
        System.out.println(integers.size());

首先看下ArrayList属性

 /**
     * Default initial capacity.
     */
    private static final int DEFAULT_CAPACITY = 10;//AraryList默认容量

    /**
     * Shared empty array instance used for empty instances.
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};//空对象数组

    /**
     * Shared empty array instance used for default sized empty instances. We
     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
     * first element is added.
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//默认空对象数组

    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer. Any
     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     * will be expanded to DEFAULT_CAPACITY when the first element is added.
     */
    transient Object[] elementData; // non-private to simplify nested class access 存储对象的数组

    /**
     * The size of the ArrayList (the number of elements it contains).
     *
     * @serial
     */
    private int size;//ArrayList的容量

执行ArrayList integers=new ArrayList();调用无参构造方法,设置对象数组为DEFAULTCAPACITY_EMPTY_ELEMENTDATA也就是{}

     public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {//初始容量>0,new一个Object数组,容量为initialCapacity
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {//初始容量为0,
            this.elementData = EMPTY_ELEMENTDATA;
        } else {//其他值,报错
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

然后执行 integers.add(2);

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;//在数组默认添加一个元素,然后size+1
        return true;
    }

该方法主要就是调用ensureCapacityInternal方法,进入到这个方法

   private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

进入到calculateCapacity(elementData, minCapacity)方法

    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//如果elementData=DEFAULTCAPACITY_EMPTY_ELEMENTDATA也就是{}
            return Math.max(DEFAULT_CAPACITY, minCapacity);//返回DEFAULT_CAPACITY和minCapacity的最大值
        }
        return minCapacity;
    }

通过calculateCapacity就得到了要修改的容量

进入到ensureExplicitCapacity方法

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;//修改次数+1

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)//判断当前要修改的容量是否大于当前数组长度
            grow(minCapacity);//扩容
    }

进入到grow方法

    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;//当前容量
        int newCapacity = oldCapacity + (oldCapacity >> 1);//新容量增加原来的0.5
        if (newCapacity - minCapacity < 0)//取newCapacity 和minCapacity的大者
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)//检验是否越界
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);//拷扩展数组容量为newCapacity,并将赋值为当前数组elementData 
    }
  public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }
    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

查看Arrays.copy方法,发现底层是用的 public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length); native方法

    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

执行integers.remove(1);

    public E remove(int index) {
        rangeCheck(index);//检验当前索引是否越界
        modCount++;//修改次数加1
        E oldValue = elementData(index);//保存旧值
        int numMoved = size - index - 1;//numMoved=4-1-1=2
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index, numMoved);
        elementData[--size] = null; // clear to let GC do its work
        //将最后一个置为null方便gc
        return oldValue;
    }

进入 rangeCheck(index);//检验当前索引是否越界

    private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

然后运行Vector测试代码

        Vector<Integer> integers1=new Vector<Integer>(10);
        integers1.add(2);
        integers1.add(1);
        integers1.add(null);
        integers1.add(null);
        integers1.remove(1);
        System.out.println(integers1.size());

查看Vector的参数

    /**
     * The array buffer into which the components of the vector are
     * stored. The capacity of the vector is the length of this array buffer,
     * and is at least large enough to contain all the vector's elements.
     *
     * <p>Any array elements following the last element in the Vector are null.
     *
     * @serial
     */
    protected Object[] elementData;//对象数组

    /**
     * The number of valid components in this {@code Vector} object.
     * Components {@code elementData[0]} through
     * {@code elementData[elementCount-1]} are the actual items.
     *
     * @serial
     */
    protected int elementCount;//对象数组长度

    /**
     * The amount by which the capacity of the vector is automatically
     * incremented when its size becomes greater than its capacity.  If
     * the capacity increment is less than or equal to zero, the capacity
     * of the vector is doubled each time it needs to grow.
     *
     * @serial
     */
    protected int capacityIncrement;//向量的大小大于其容量时,容量自动增加的量。如果容量的增量小于等于零,则每次需要增大容量时,向量的容量将增大一倍。

Vector构造方法

  public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)//初始容量<0,抛异常
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];//new一个容量为initialCapacity的对象数组
        this.capacityIncrement = capacityIncrement;//设置capacityIncrement,如果capacityIncrement 不为0,扩容时候每次增加capacityIncrement 
    }

    /**
     * Constructs an empty vector with the specified initial capacity and
     * with its capacity increment equal to zero.
     *
     * @param   initialCapacity   the initial capacity of the vector
     * @throws IllegalArgumentException if the specified initial capacity
     *         is negative
     */
    public Vector(int initialCapacity) {
        this(initialCapacity, 0);//capacityIncrement默认为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);//initialCapacity为10
    }

然后add、remove和ArrayList几乎一模一样,
区别只在于扩容部分
以下为Vector扩容部分源码

    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;//计算旧对象数组长度
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);//如果直到增长量,那么增长量为capacityIncrement ,否则扩容为原来的2倍
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

对比ArrayList扩容源码

  private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;//当前容量
        int newCapacity = oldCapacity + (oldCapacity >> 1);//新容量增加原来的0.5
        if (newCapacity - minCapacity < 0)//取newCapacity 和minCapacity的大者
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)//检验是否越界
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);//拷扩展数组容量为newCapacity,并将赋值为当前数组elementData 
    }

因此Vector可以设置自动增长容量,如果不设置自动增长容量,扩容后容量为原来的2倍,而ArrayList扩容后的容量为原来的1.5倍,因此Vector更占用空间
只是加了synchronized,因此Vector是线程安全的,因此性能不如ArrayList

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值