ArrayList扩容机制

ArrayList使用默认构造方法会生成一个长度为0list,在调用add()方法的时候会进行扩容,细说一下扩容机制。

首先,先来看ArrayList中的一些参数:

//默认初始容量大小
private static final int DEFAULT_CAPACITY = 10;

//空数组
private static final Object[] EMPTY_ELEMENTDATA = {};

//用于默认大小空实例的共享空数组实例。
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

//保存的数据
transient Object[] elementData;
private int size;

接着来看构造函数:

public ArrayList() {
 	this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

可以发现,使用无参构造的时候构造的是一个空的数组实例,长度为0,当对数组元素进行添加的操作的时候,会扩容容量到10;接下来看看add()的过程

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

调用add()方法的时候会调用一个ensureCapacityInternal(size + 1)方法:

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

 private static int calculateCapacity(Object[] elementData, int minCapacity) {
     if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
         return Math.max(DEFAULT_CAPACITY, minCapacity);
     }
     return minCapacity;
 }

进入ensureCapacityInternal(size + 1)方法后,会调用一个ensureExplicitCapacity方法,传递的参数为默认容量(10)和传入参数的最大值,第一次add传入的参数为1;

 private void ensureExplicitCapacity(int minCapacity) {
     modCount++;

     // overflow-conscious code
     if (minCapacity - elementData.length > 0)
         grow(minCapacity);
 }

在第一次添加元素执行到这个方法的时候,传入的minCapacity为10,符合判断条件,进入grow方法:

 //要分配的最大数组大小
 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

 private void grow(int minCapacity) {
     // overflow-conscious code
     //old为旧容量,new为新的容量
     int oldCapacity = elementData.length;
     //可以看出,扩容是使用的位运算,相当于/2,但是效率要高;
     //扩容为本来容量的1.5倍左右
     int newCapacity = oldCapacity + (oldCapacity >> 1);
     //如果扩容后的容量还是不够,那么就把最小的需要容量置为扩容后的容量
     if (newCapacity - minCapacity < 0)
         newCapacity = minCapacity;
     //如果扩容后的容量大于最大的数组容量,进入hugeCapacity方法
     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);
 }


 private static int hugeCapacity(int minCapacity) {
     if (minCapacity < 0) // overflow
         throw new OutOfMemoryError();
     //如果所需的最小容量大于最大数组大小,那么扩容后的容量为Integer的最大值,
     //否则为最大的数组大小,
     return (minCapacity > MAX_ARRAY_SIZE) ?
         Integer.MAX_VALUE :
         MAX_ARRAY_SIZE;
 }

到此,扩容结束;再次add元素的时候,minCapacity - elementData.length > 0 不成立,直接在数组后面添加元素并让size++,直到添加第11个元素

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值