JDK1.8,ArrayList空参构造,动态扩容机制,主要方法分析

当第一次调用add方法添加元素时,方法调用流程
1、ensureExplicitCapacity(int minCapacity) {…}方法,判断是否需要扩容,其中:
modCount++; if (minCapacity - elementData.length > 0) grow(minCapacity);
minCapacity表示预期的数组最小容量值,elementData.length表示的当前实际数组长度,如果是空参构造方法去创建集合,那么可知此时传入到这个方法的minCapacity为10,而实际一开始我们创建的空集合List arrList = new ArrayList(),长度为0,那么这个判断为true,“表示现在向list集合add元素,底层数组已经无法存储更多的元素了”。所以会进入grow方法进行扩容。minCapacity - elementData.length > 0,可以理解为当前数组是否能存放下minCapacity个元素。
特别注意这里针对的是ArrayList的无参构造。此时的elementData是我们初始化时的空数组,数组长度为0,只有在add元素时才会扩容为10,在没有完成grow方法前,所有代码中涉及的elementData数组都是个空数组,length为0。

2、至于grow(minCapacity)方法就比较好理解了, int oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0) newCapacity = minCapacity;在完成第一次向空数组添加元素后 ,完成第一次数组扩容后的elementData.length 已经为10了 ( 第一次add时,if(0-10 < 0) 为返回true, newCapacity = minCapacity = 10)。当添加第11个元素时,这个if(15-10<0)判断不成立,进行扩容的新数组长度newCapacity 为15。这两段代码说明了为什么会扩为原来数组长度的1.5倍,“oldCapacity >> 1”可表示为oldCapacity / 2。后面还会判断newCapacity 与MAX_ARRAY_SIZE(最大数组长度)的大小,调用newCapacity = hugeCapacity(minCapacity);这个就不分析,MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8,也就是2147483647 -8。以上就确定了新数组的长度newCapacity,最后调用elementData = Arrays.copyOf(elementData, newCapacity);实际是调用System.arraycopy()完成新数组的创建。
总结就是:以无参构造方法创建 ArrayList 时,实际上初始化赋值的是一个空数组。当真正对数组进行添加元素操作时,才真正分配容量。即向数组中添加第一个元素时,数组扩容为10。

3、另外ArrayList提供一个对外可调用的方法, ensureCapacity方法
该方法中 :
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) ? 0 : DEFAULT_CAPACITY; //判断elementData是否是通过无参构造的(空数组),是 取反则为 false 返回 DEFAULT_CAPACITY 默认值为10
否则取反为 true 返回0。
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
//这个地方minCapacity为指定的容量,minExpand可以理解为是最小需要扩充的容量(据上述分析,用户可以指定数组的长度,这个方法是显示的去分配底层数组容量,以减少递增式再分配的次数)。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值