集合ArrayList底层代码学习
ArrayList
底层代码:
底层定义了一个elementData数组来存数据,返回值为Object的数组
当我们new 一个无参的ArrayList时,集合容量是 0,当向集合中第一次添加数据时,会自动扩容到容量为10,当向集合中添加数据容量不够(下面会讲怎样扩容)时,会扩容为原来的1.5倍 也就是 15 然后是 15*1.5 。。。(15 + 15 >> 1 => 15 + 15/2 =22)
ArrayList<Object> objects = new ArrayList<>();
当我们new 一个有参的ArrayList构造器时 ,集合容量初始化就是定义的容量,第一次扩容是就是定义的容量的1.5倍
ArrayList<Object> arrayList = new ArrayList<>(50);
transient :表示该属性不会被序列化
什么情况下会扩容??怎样扩容?
集合中add方法中 ensureCapacityInternal(size+1)
方法会先判断是否需要扩容,然后再赋值,先看下ensureCapacityInternal(size+1)
方法
方法解读:如果这个elementData是个空数组,那么就给他赋最小容量, 最小容量就是Math.max() 方法中间的两个参数比较的最大值,第一次传进来就是10 和 空的比 ,10最大,那么容量就是10
继续进入下面的ensureExplicitCapacity(minCapacity)
看下源码
modCount记录当前集合被修改的次数,在多线程的情况下进行修改的记录
接下来判断如果当前的集合的容量比要添加的集合的容量小,那么就要进行扩容
grow(minCapacity)
第一次扩容时会进到256行的代码 (0-10<0)会把minCapacity(容量为10)赋值给newCapacity ,新的容量就是10,之后的扩容的话就会按照1.5倍扩容
elementData = Arrays.copyOf(elementData,newCapacity);
为什么用copyOf:
会保留之前的数据,避免数据丢失,再增加一些空间
这样就完成了无参ArrayList的扩容!
注意!!!
Idea 在默认的情况下Debug显示的数据时简化后的,看到完整数据需要做设置,去掉红线的勾选
debug情况扩容后显示