ArrayList源码分析
ArrayList集合源码分析
ArrayList的扩容机制
ArrayList中维护了一个Object类型的数组elementData
1
transient Object[] elementData; // 非私有,以简化嵌套类访问非私有,以简化嵌套类访问
当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第一次添加,则扩容elementData为10,如果需要再次扩容,则扩容elementData为1.5倍。
如果是使用的指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍。
1 | import java.util.ArrayList; |
1 | public ArrayList() { |
1.无参构造器,初始elementData的容量为0
1 | public boolean add(E e) { |
2.add方法,add()方法内部
2.1 E e:这个方法的入参类型是一个泛型,可以是String,Student等类型
2.2 ensureCapacityInternal(size + 1) :首先进入这个方法判断是否需要扩容
2.3 elementData[size++] = e :将要添加的元素的值赋给数组的第size个元素,然后size自增1
1 | private void ensureCapacityInternal(int minCapacity) { |
3.ensureCapacityInternal(size + 1)方法内部
3.1 int minCapacity:字面意思 最小容量
3.2 calculateCapacity(elementData, minCapacity) : 分析见第4点
3.3 ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)) :分析见第5点
1 | private static int calculateCapacity(Object[] elementData, int minCapacity) { |
4.calculateCapacity(elementData, minCapacity)方法内部
4.1 判断elementData的容量是否为0,如果为0,返回一个默认值:10;如果不为0,则直接返回传过来的最小容量
1 | private void ensureExplicitCapacity(int minCapacity) { |
5.ensureExplicitCapacity(calculateCapacity(elementData, minCapacity))方法内部
5.1 int minCapacity:将上一个方法确定的最终的容量传进来
5.2 modCount++ :modCount自增1,modCount表示修改次数,每增加一个元素,modCount都会增加1
拓展:在这些线程不安全的集合中,在某些方法中,初始化迭代器时会给这个modCount赋值,
如果在遍历的过程中,一旦发现这个对象的modCount和迭代器存储的modCount不一样,就会报错。
5.3 minCapacity与elementData的长度进行比较,如果大于0,就会进行扩容(grow(minCapacity)方法见第6点),否则直接返回
1 | private void grow(int minCapacity) { |
6.grow(int minCapacity)方法,真正扩容的地方
6.1 定义oldCapacity、newCapacity两个容量分别表示原来的容量和最新的容量。
oldCapacity的大小为elementData的大小
newCapacity的大小为原来的1.5倍
6.2 判断最新的容量和需要的最小容量进行比较,如果最新的容量比需要的最小容量还要小,那么将最新的容量更新为所需要的最小 的容量;否则不变
6.3 判断最新的容量是否大于规定的最大容量(一般不会),hugeCapacity(minCapacity)方法暂不分析
6.4 Arrays.copyOf(elementData, newCapacity):将elementData进行扩容,扩容至最新的大小