JAVA集合篇之ArrayList底层源码(JDK8)

ArrayList有三个构造方法

1.ArrayList()

ArrayList arrayList = new ArrayList();

分析:

/**
 * Constructs an empty list with an initial capacity of ten.创建空集合,初始容量10
 * transient Object[] elementData;集合存元素的变量
 * private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};默认空容量对象
 */
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

//调用空构造器的时候,会将elementData赋值为空对象数组。

//此时添加元素,调用add(E e)方法。

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

//添加元素之前会确认容量,调用ensureCapacityInternal方法

private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); }

//第一次调用的时候,minCapacity = size + 1 (size第一次添加时为0,因此minCapacity  = 0 + 1 = 1)

//调用此方法calculateCapacity(elementData, minCapacity)

//该方法计算最小容量值

private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//第一次添加时,满足条件
        return Math.max(DEFAULT_CAPACITY, minCapacity);//得到最小容量,即minCapacity = 10
    }
    return minCapacity;
    }

//ensureExplicitCapacity(10),这里的参数为上一步计算得到的最小容量值10

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;//记录修改次数,主要用于多线程 provide fail-fast iterators
    // overflow-conscious code
    if (minCapacity - elementData.length > 0) //此时,elementData.length第一次添加时为0
        grow(minCapacity); //进行扩容
}

//此方法为真正扩容方法,此时 minCapacity = 10

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length; //记录旧集合的元素个数,此时为0
    //在旧容量的基础上,扩容1.5倍(右移1位相当于/2)
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0) //第一次的时候集合元素为空,newCapacity = 0,
        newCapacity = minCapacity;     //newCapacity  = 10 第一次扩容,容量为10
    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); //进行数组拷贝,扩容为10
}

//扩容完成以后,容量为10,第一个元素被添加进去

//此后继续添加元素时,重复以上方法,在添加的元素数量未达到容量10时,不会进行扩容操作

//即以下判断不成立

if (minCapacity - elementData.length > 0)
    grow(minCapacity);

//直到添加第11个元素,即添加的数量超过当前集合的容量时,该if判断条件成立,进入grow(minCapacity)方法,此时minCapacity = 11

// minCapacity = 11,该方法为真正扩容方法

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);
    // minCapacity is usually close to size, so this is a win:
    //进行扩容,将原来数组的元素拷贝到新数组,扩容为原来的1.5倍
    //实际调用的扩容方法为:System.arraycopy(original, 0, copy, 0,
                 Math.min(original.length, newLength));
    elementData = Arrays.copyOf(elementData, newCapacity);
}

//此后,添加的逻辑相似,当添加的元素数量又大于当前容量时扩容1.5,以此类推。

2.调用有参构造函数 ArrayList arrayList = new ArrayList(8);

分析:

/**
 * Constructs an empty list with the specified initial capacity.
 *
 * @param  initialCapacity  the initial capacity of the list
 * @throws IllegalArgumentException if the specified initial capacity
 *         is negative
 * private static final Object[] EMPTY_ELEMENTDATA = {};
 */
public ArrayList(int initialCapacity) { // initialCapacity = 8
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity]; //构造一个初始容量的Object数组
    } else if (initialCapacity == 0) { //如果构造函数的参数为0,则赋值为空对象数组
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

//执行添加方法,逻辑和无参构造走的方法一模一样

//只不过调用到这里的时候elementData不是空数组,而是初始容量为构造参数值 = 8的对象数组

private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //条件不成立
        return Math.max(DEFAULT_CAPACITY, minCapacity); 
    }
    return minCapacity; //这里返回8 minCapacity = 8
    }

//之后的逻辑与无参构造执行的添加逻辑一样,也是先确认是否需要扩容,然后再执行其他操作,只不过现在的扩容是在8(构造参数中的值)的基础上扩容1.5倍。

  • 24
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值