目录
2.2ArrayList(int initialCapacity)
1.ArrayList 扩容机制
ArrayList
扩容的本质就是计算出新的扩容数组的size
后实例化,并将原有数组内容复制到新数组中去。(不是原数组,而是新数组然后给予数组对象地址)。- 当无参创建一个ArrayList对象时,它会分配一定的初始容量,通常为10。
- 当ArrayList中的元素数量达到当前容量时,ArrayList会自动增加其容量。
ArrayList
扩容的计算是在一个grow()
方法里面,grow
方法先尝试将数组扩大为原数组的1.5倍。(默新容量=旧容量右移一位(相当于除于2)在加上旧容量) - 若新的容量满足需求,会调用一个
Arrays.copyof
方法, 将所有的元素从旧数组复制到新数组中,这个方法是真正实现扩容的步骤。如果扩容后的新容量还是不满足需求,那新容量大小为当前所需的容量加1。
2.底层代码分析
以JDK8版本为例。
2.1ArrayList()
演示的测试代码及断点位置
1. 进入断点第6行查看ArrayList()的构造器
说明:
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;代码的作用。
给elementData 数组赋值为空。
(1)elementData 数组?
elementData 数组是ArrayList的一个属性,被transient修饰,故不可被序列化。
(2)DEFAULTCAPACITY_EMPTY_ELEMENTDATA?
2.查看第8行arrayList.add(0)的源码
ArrayList
中只能存储对象。对于基本类型数据,需要使用其对应的包装类
(1)先会进行基本类型->包装类的封装
(2)然后进入add方法
说明:
size是此时的elementData 数组中的元素个数。
ensureCapacityInternal故名思意是 确保内部容量
(3)进入ensureCapacityInternal(size + 1)
说明:
1.size+1==minCapacity 意思是此次添加元素起码要有的容量。
2.calculateCapacity意思是计算容量。
3.ensureExplicitCapacity意思是确定容量。calculateCapacity方法的返回值为ensureExplicitCapacity的参数。
(4)进入calculateCapacity方法
说明:DEFAULT_CAPACITY==10 ,是默认值;
解释代码:
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity;
1.if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
意思是如果 elementData是空的数组,就让DEFAULT_CAPACITY和minCapacity比大小。
1.当elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA成立时,一定是空ArrayList第一次添加元素。
2.DEFAULT_CAPACITY和minCapacity比大小就是10和1比大小。
小结:calculateCapacity方法发挥作用就只是在elementData第一次添加元素时,设置默认数组大小10.
(5)进入ensureExplicitCapacity 方法
说明:modCount 为修改次数。
解释代码:
if (minCapacity - elementData.length > 0) grow(minCapacity);
意思是 elementData数组此时的容量小于添加元素后起码要有的最小容量,此时就要执行grow(minCapacity) 方法进行扩容。
(6)执行grow方法进行扩容
解释代码1:
int newCapacity = oldCapacity + (oldCapacity >> 1);
newCapacity = oldCapacity + 0.5*oldCapacity;
新容量为旧容量1.5倍。
解释代码2:
if (newCapacity - minCapacity < 0) newCapacity = minCapacity;
意思是新容量如果还没有添加元素后起码要有的最小容量大, newCapacity = minCapacity
解释代码3:
elementData = Arrays.copyOf(elementData, newCapacity);
调用一个Arrays.copyof
方法, 将所有的元素从旧数组复制到新数组中,这个方法是真正实现扩容的步骤.
3. 进入断点第10行和第13行后
进入断点第10行后此时arrayList的数组容量为15.
进入断点第13行后此时arrayList的数组容量为22.
2.2ArrayList(int initialCapacity)
意思非常简单就是 initialCapacity>0,就按initialCapacity的大小创建集合,initialCapacity==0,就按10的大小创建集合,initialCapacity<0就报错。
想了解更多ArrayList相关:
ArrayList的详解_1. arraylist-优快云博客
以上为我个人的小分享,如有问题,欢迎讨论!!!
都看到这了,不如关注一下,给个免费的赞