您的位置:首页 > 其它

ArrayList的扩容机制

2016-11-02 09:52 302 查看
文章出处:http://man-yutao.iteye.com/blog/1317446

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

Java代码  


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的扩展方法 

Java代码  


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

}  

   }  

重构下看起来更方便 

Java代码  


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的扩容方法 

Java代码  


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

将上面生成的新数组长度与传递的参数要求长度作比较,较大者为最终的新长度。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: