ArrayList和Vector的扩容机制

本文对比分析了ArrayList与Vector两种集合类的区别,重点介绍了它们的内部属性及扩容机制的不同。ArrayList通过调整数组大小来实现扩容,而Vector则依赖于扩展因子进行扩容。

ArrayList和Vector都是继承了相同的父类和实现了相同的接口。如下

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

两者之间我认为主要有两个却别。
1、Vector中的public方法都添加了synchronized关键字,以确保方法同步。
2、内部属性不同,这也是导致扩容方式不同的原因所在。

我现在来说第二条,
ArrayList有两个属性,存储数据的数组elementData,和存储记录数目的size。
Vector有三个属性,存储数据的数组elementData,存储记录数目的elementCount,还有扩展数组大小的扩展因子capacityIncrement。

先来看ArrayList的扩展方法 

    public void ensureCapacity(int minCapacity) {  
    modCount++;//父类中的属性,记录集合变化次数  
    int oldCapacity = elementData.length;  
    if (minCapacity > oldCapacity) {  
        Object oldData[] = elementData;  
        int newCapacity = (oldCapacity * 3)/2 + 1;  
            if (newCapacity < minCapacity)  
        newCapacity = minCapacity;  
        elementData = (E[])new Object[newCapacity];  
        System.arraycopy(oldData, 0, elementData, 0, size);  
    }  
       }  

重构下看起来更方便

    public void ensureCapacity(int minCapacity) {  
    modCount++;//父类中的属性,记录集合变化次数  
    int oldCapacity = elementData.length;  
    if (minCapacity > oldCapacity) {//扩容的条件,数组需要的长度要大于实际长度  
        Object oldData[] = elementData;  
        int newCapacity = ((oldCapacity * 3)/2 + 1)<minCapacity?minCapacity: ((oldCapacity * 3)/2 + 1);  
           elementData = (E[])new Object[newCapacity];  
        System.arraycopy(oldData, 0, elementData, 0, size);  
    }  
       }  

 可以看到,再满足扩容条件时,扩展后数组大小为((原数组长度*3)/2+1)与传递参数中较大者

再看看Vector的扩容方法 

    public synchronized void ensureCapacity(int minCapacity) {  
        modCount++;//父类中的属性,记录集合变化次数  
        ensureCapacityHelper(minCapacity);  
        }  
     private void ensureCapacityHelper(int minCapacity) {  
        int oldCapacity = elementData.length;  
        if (minCapacity > oldCapacity) {//扩容的条件,数组需要的长度要大于实际长度  
            Object[] oldData = elementData;  
            int newCapacity = (capacityIncrement > 0) ?  
            (oldCapacity + capacityIncrement) : (oldCapacity * 2);  
                if (newCapacity < minCapacity) {  
            newCapacity = minCapacity;  
            }  
            elementData = new Object[newCapacity];  
            System.arraycopy(oldData, 0, elementData, 0, elementCount);  
        }  
        }  

可以看到,相对于ArrayList的扩容方法,这个方法被一分为2,老实说我更喜欢这样,方法的职责更加明确。

int newCapacity = (capacityIncrement > 0) ?(oldCapacity + capacityIncrement) : (oldCapacity * 2);

当扩容因子大于0时,新数组长度为原数组长度+扩容因子,否子新数组长度为原数组长度的2倍。

if (newCapacity < minCapacity) {newCapacity = minCapacity;}

将上面生成的新数组长度与传递的参数要求长度作比较,较大者为最终的新长度。 

转载于:https://www.cnblogs.com/wuxiang/p/5328241.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值