ArrayList的扩容机制

来源:互联网 发布:sql脚本编写教程 编辑:程序博客网 时间:2024/06/06 01:43

ArrayList是基于数组实现的,是一个动态的数组,其容量可以自动的增长,我们具体来看一下Arraylist的扩容机制的主要源码。

   public boolean add(E e) {        ensureCapacityInternal(size + 1);  // Increments modCount!!        elementData[size++] = e;//每次增加一个元素,会自增一        return true;    }   public void ensureCapacity(int minCapacity) {        if (minCapacity > 0)            ensureCapacityInternal(minCapacity);    }    private void ensureCapacityInternal(int minCapacity) {        modCount++;//这是继承抽象list父类,用于记录结构修改的次数        // overflow-conscious code        //如果数组(elementData)的长度小于最小需要的容量(minCapacity)就扩容        if (minCapacity - elementData.length > 0)            grow(minCapacity);    }     private void grow(int minCapacity) {        // overflow-conscious code        int oldCapacity = elementData.length;        int newCapacity = oldCapacity + (oldCapacity >> 1);        //再判断一下新数组的容量够不够,够了就直接使用这个长度创建新数组,         //不够就将数组长度设置为需要的长度        if (newCapacity - minCapacity < 0)            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);    }

在每次add一个新元素时候,会进行一个容量的判断, ensureCapacityInternal(size + 1); 如果数组(elementData)的长度小于最小需要的容量(minCapacity)就扩容,进入到扩容的主要方法,grow(minCapacity)。
通过以上代码,我们可知java自动增加ArrayList大小的思路是:向ArrayList添加对象时,原对象数目加1如果大于原底层数组长度,则以适当长度新建一个原数组的拷贝,并修改原数组,指向这个新建数组。原数组自动抛弃(java垃圾回收机制会自动回收)。size则在向数组添加对象,自增1。
举个例子在阐述一下该实现机制的过程,我们初始化一个list,默认的容量为10,我们在增加第11个元素的时候,执行ensureCapacityInternal(size + 1),也就是传入11,进入ensureCapacityInternal方法,此时minCapacity的值为11,数组的长度为10,此时minCapacity-elementData.length > 0,需要执行扩容的方法,具体扩容的方式为扩充为10的1.5倍即可。