ArrayList集合的底层原理
①利用无参构造器创建的集合,会在底层创建一个默认长度为0的数组
②添加第一个元素时,底层会创建一个新的长度为10的数组
③存满时,会扩容1.5倍
④如果一次添加多个元素,1.5倍还放不下,则新创建数组的长度以实际为准
点击查看代码
package com.itheima.javase;
import java.util.ArrayList;
/**
* TODO: ArrayList集合的底层原理
* ①利用无参构造器创建的集合,会在底层创建一个默认长度为0的数组
* ②添加第一个元素时,底层会创建一个新的长度为10的数组
* ③存满时,会扩容1.5倍
* ④如果一次添加多个元素,1.5倍还放不下,则新创建数组的长度以实际为准
*/
public class ArrayListDemo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i);
}
list.add(-1);
}
/*
ArrayList<Integer> list = new ArrayList<>();
用无参构造器创建ArrayList集合,JVM自动调用public ArrayList(){}
elementData是一个可以存储任意类型的对象的数组,并且这个变量在对象被序列化时不会被写入到输出流中。
DEFAULTCAPACITY_EMPTY_ELEMENTDATA是ArrayList的私有静态常量数组,这个数组是空的,可以存储任意类型的对象。
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
至此,利用无参构造器创建的集合,会在底层创建一个默认长度为0的数组,证毕
for (int i = 0; i < 10; i++) {
list.add(i);
}
当集合添加1个元素,会调用add()方法,随后会有一系列方法的嵌套调用,
boolean add(E e)
E是泛型(Integer) e是元素i
add---------->ensureCapacityInternal---------->ensureExplicitCapacity(calculateCapacity(elementData, minCapacity))---------->grow(minCapacity)
void ensureCapacityInternal(size + 1)
因为size是ArrayList类的一个私有成员变量,初始值是0
所以演变成void ensureCapacityInternal(1)
记住,此时minCapacity=1
void ensureCapacityInternal(int minCapacity)
在方法ensureCapacityInternal中会调用ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
其中方法calculateCapacity(elementData, minCapacity)的返回值作为参数传入方法ensureExplicitCapacity中
故先看方法calculateCapacity(elementData, minCapacity)
elementData=DEFAULTCAPACITY_EMPTY_ELEMENTDATA [new ArrayList()已证]
int calculateCapacity(Object[] elementData, int minCapacity){
不难看出方法calculateCapacity的返回值是return Math.max(DEFAULT_CAPACITY, minCapacity);
DEFAULT_CAPACITY是ArrayList类的一个常量,值为10
即是ensureExplicitCapacity(10);
void ensureExplicitCapacity(int minCapacity)中
if (minCapacity - elementData.length > 0) 10-0>0条件为真
进而调用grow(minCapacity);
void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
其中oldCapacity=0,newCapacity=0>>1,右移1位,还是0
newCapacity - minCapacity=0-10=-10<0,条件为真,故newCapacity=10,最后执行elementData = Arrays.copyOf(elementData, newCapacity);
即底层会创建一个新的长度为10的数组,证毕
当for循环执行完毕结束,此时,list.size=10,我们再次向集合中添加一个元素,同样调用add方法,
有add---------->ensureCapacityInternal---------->ensureExplicitCapacity(calculateCapacity(elementData, minCapacity))---------->grow(minCapacity)
只不过在grow(minCapacity)方法中minCapacity=size+1=11
int oldCapacity = elementData.length; 10
newCapacity = oldCapacity + (oldCapacity >> 1); 10+5=15
newCapacity - minCapacity < 0 不满足 15-11=4>0
newCapacity - MAX_ARRAY_SIZE > 0 不满足 15-(Integer.MAX_VALUE - 8)<0
两个if条件都不满足,继而执行elementData = Arrays.copyOf(elementData, newCapacity);
此时newCapacity为15,即存满时,会扩容1.5倍,证毕
*/
}
浙公网安备 33010602011771号