分析ArrayList源码
先说结论,下面是源码分析
- Array List中维护了一个Object类型的数组,elementData[deBug看源码上看的很清楚]
- 当创建ArrayList对象时,如果使用的是无参构造器,则初识elementData容量为 0,第一次添加则扩容elementData容量为10,如果需要再扩容,则扩容elementData为原先的1.5倍
- 如果使用的数指定大小的构造器,则初始大小为elementData的指定大小,如果需要继续扩容则,则直接扩容elementData为1.5倍
分析使用无参构造器的创建和使用ArrayList的源码
- 底层创建了一个空的 elementDATA数组
- 执行list.add()方法,
- 第一步先判断数组的容量是否足够我再添加一个,
- 第二步才将我们传入的对象传入,完成赋值的操作,
-
追入ensureCapacityInternal方法,该方法确定mincapacity
-
minCapacity指的是源数组中存储的元素个数加上将要存储的元素个数,这里第一次add()时,minCapacity为1,数组的长度为0,数组内存不够,故,进行扩充
-
当最小容量减去刚创建时的容量(0),时大于0,则进行第一次扩容,扩容量为10
-
if语句是判断是否需要进行扩容的语句,注意:虽然每次循环都会进行检测是否需要扩容,但并不是每次都会进行扩容,只有elementData不够时(也就说明容量不足时)才会进行扩容。
-
-
grow()方法扩容的机制
-
注意:扩容使用的是 Array copyof( )机制,也就是说在扩容时,会保留原本的数据
-
第一次扩容比较特别,第一次为10,
-
之后都是oldCapacity + (oldCapacity >> 1),也就是oldCapacity 的1.5倍扩容
-
int oldCapacity = elementData.length; //先将第一次数组大小(0)赋给oldCapacity //所以下方第一次判断{if (newCapacity - minCapacity < 0)}时就能, //将minCapacity(10)的容量赋给oldCapacity int newCapacity = oldCapacity + (oldCapacity >> 1); //它的意思是原先数组的大小,加上原先数组的大小/2,变为新的数组newCapacity 的大小 //因为第一次扩容为10,所以就是10+10/2,也就是10的1.5倍 //>>位运算符,对正数来说相当于除以2
-
- 扩容后的空间示意
- 扩容后多出来的空间就是用null表示
如果是有参构造
- 第一次扩容,就按照elementData的1.5倍扩容
- 整个执行流程还是和前面的一样的。