ArrayList自动扩容原理

ArrayList自动扩容原理

一、ArrayList三种初始化

1、默认的构造器,将会以默认的大小来初始化内部的数组

public ArrayList();

2、用一个ICollection对象来构造,并将该集合的元素添加到ArrayList

public ArrayList(Collection<? extends E> c)

3、用指定的大小来初始化内部的数组

public ArrayList(int initialCapacity)

二、扩容概括

     扩容概括为两步:

     1、扩容---把原来的数组复制到另一个内存空间更大的数组中

     2、添加元素---把新元素添加到扩容以后的数组中

下面详细介绍扩容代码的实现原理和方法之间的调用关系

三、自动扩容从ArrayList初始化开始

1、无参构造方法:创建一个空数组

transient Object[] elementData;
private static final Object[] EMPTY_ELEMENTDATA = {};


/**
 *无参构造方法实现创建一个空数组,并且为这个数组赋一个空值
 *
*/
public ArrayList() {
        super();
        //为数组赋空值
        this.elementData = EMPTY_ELEMENTDATA;    
    }

2、扩容从add( )开始

 /**
     *1、 ArrayList 扩容从add()开始
     *2、add方法有两条语句如下:
     *   ensureCapacityInternal(size + 1); 判断是否需要调用扩容方法
     *   elementData[size++] = e;  调用add方法添加的值赋值给数组。
     * 
     */
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

3、ensureCapacityInternal:判断是否需要扩容

    //1、add方法调用ensureCapacityInternal方法
private void ensureCapacityInternal(int minCapacity) {
    //2、判断当前数组是否为空
        if (elementData == EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
    //3、调用扩容判断的方法,将当前最小扩容值传进去。
        ensureExplicitCapacity(minCapacity);
    }

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
    
     /**
     * 4、minCapacity:最小扩容值
     *elementData.length:数组空间长度
     * 判断是否扩容原理:
     * (最小扩容值 - 数组空间长度 > 0)则调用扩容方法grow(minCapacity);
     * 举例:第一次调用add方法,最小扩容值为11,数组长度为10 那么(11- 10 > 0)调用扩容,扩容后是当 
     *前值的1.5倍=15。            
     * 第二次调用add方法,最小扩容值+1是12,数组长度为15那么(12- 15 > 0)不大于0,不调用扩容方法
     */
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

4、grow(minCapacity) :计算扩容空间大小,并调用复制数组方法。

    private void grow(int minCapacity) {
        // overflow-conscious code
    //1、获取现在数组的长度
        int oldCapacity = elementData.length;
    //2、扩容后的数组长度
    //  oldCapacity >> 1    右移运算符   原来长度的一半 再加上原长度也就是每次扩容是原来的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
    //3、判断扩容后的长度是否小于需要的最小扩容
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
    //4、判断扩容后的长度是否超过规定的最大值
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
    //5、调用复制数组方法,将老的数组复制到新的数组中,并将需要添加的元素加到数组最后一位
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值