ArrayList增加扩容问题 源码分析

public class ArrayList<E>{
    private static final int DEFAULT_CAPACITY = 10;//默认的容量是10
    private static final Object[] EMPTY_ELEMENTDATA = {};//长度为空的时候的数组,不可变的
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//默认长度的空数组
    transient Object[] elementData; //使用中的临时可变化的数组
    private int size;//数组中的个数
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    protected transient int modCount = 0;//
    
    public void ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];//新建一个
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;//默认是0,就把空数组复制给它
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);//参数非法异常
        }
    }

    public void ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//空参的情况下默认0的数组赋值给它
    }
    
    
    /*增加*/
     public boolean add(E e) {
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            elementData[size++] = e;
            return true;
        }
    
     /*检查是否需要扩容*/
        private void ensureCapacityInternal(int minCapacity) {
            //如果数组是空数组,最小容量赋值为默认10
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }

            ensureExplicitCapacity(minCapacity);
        }
        /*确定扩容的大小
         * elementData是用来存储实际内容的数组。minExpand 是最小扩充容量。 
         * DEFAULTCAPACITY_EMPTY_ELEMENTDATA共享的空数组实例用于默认大小的空实例。
         * 根据传入的最小需要容量minCapacity来和数组的容量长度对比,若minCapactity大于或等于数组容量,则需要进行扩容。
         * 
         * 
         * */
        private void ensureExplicitCapacity(int minCapacity) {
            modCount++; //AbstractList.class中的值 

            // overflow-conscious code 检测到溢出情况下的代码
            //如果最小所需容量>数组长度,就需要扩容 
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
        
        /*扩容操作*/
        private void grow(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;
            int newCapacity = oldCapacity + (oldCapacity >> 1);//默认的相当于1.5倍?
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;//如果还是不够,就把需要的值赋值
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);//判断newCapacity大容量情况,考虑minCapacity
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
        
        /*大容量处理*/
        private static int hugeCapacity(int minCapacity) {
            if (minCapacity < 0) // overflow
                throw new OutOfMemoryError(); //如果minCapacity小于0 ,内存溢出
            return (minCapacity > MAX_ARRAY_SIZE) ? 
                Integer.MAX_VALUE : //如果minCapacity也大于MAX_ARRAY_SIZE
                MAX_ARRAY_SIZE; //否则扩容到MAX_ARRAY_SIZE
        }
        
     /*   综上所述,ArrayList相当于在没指定initialCapacity时就是会使用延迟分配对象数组空间,
        当第一次插入元素时才分配10(默认)个对象空间。假如有20个数据需要添加,那么会分别在第一次的时候,
        将ArrayList的容量变为10 ,之后扩容会按照1.5倍增长。也就是当添加第11个数据的时候,
        Arraylist继续扩容变为10*1.5=15;当添加第16个数据时,继续扩容变为15 * 1.5 =22个
        在JDK1.7中,如果通过无参构造的话,初始数组容量为0,当真正对数组进行添加时,才真正分配容量。
      每次按照1.5倍(位运算)的比率通过copeOf的方式扩容。 
            在JKD1.6中,如果通过无参构造的话,初始数组容量为10.每次通过copeOf的方式扩容后容量为原来的1.5倍加1。
        *
        */
        
}
原文地址:https://www.cnblogs.com/pikaqiucode/p/8244121.html