ArrayList - 源码分析 - 指南
ArrayList - 源码分析
先分析一下源码

进到构造方法中看一下,允许看到有三个构造方法。接下来再看一下成员变量


通过OK,我们创建的是一个没有参数的数组,那么就会走无参的构造方法,无参的构造方法中,也只是帮我们创建了数组,那么我们再看一下如果我向数组中添加技巧会发生什么?能够看到,调用了Add方法,参数是一个泛型,里面又调用了一个add方法,参数,一个是我们传的1,一个是真正存放数据的数组,还有一个是数组的长度,那么我们就跟进去看一下。


一个空的集合 = 0。跟到grow方法中看一下就是该add里面,size判断了一下elementData的长度,如果不满足那么,我们传的1会被放到数组的最后的位置,并且size+1。如果size = elementData的长度,就会调用一个方法。我们第一次传1那么一定是满足这个条件的,因为size = 0 elementData

size + 1 那么这时候 size = 1了继续跟进去。

minCap这个时候就是 1 ,oldCap等于elementData的长度 那么就是 0 ,看一下判断语句,old > 0 不满足,elementData != DEF,这个DEF也是一个空的集合,那么这个也不满足条件,直接走else,else中new 了一个 集合 并且容量是 max,max里面的参数,第一个参数就是我们之前看的成员变量默认是10,第二个参数就是传过来的1,那么取最大值10,并返回给elementData,那么这个时候elementData的容量就是10了。既然这样就说明,我们在创建数组的时候如果没有指定容量,那么容量就是0。只有在第一次进行添加的时候才会进行扩容。接下来我们来看一下,第2-10次添加会怎么样。

这里2-10次添加其实都是一样的,因为此时的数组容量已经是10了,添加的时候只要数组的容量不超过10就是一样的了。那么我们来分析一下为什么?

重新来到add方法中,该方法中,判断一定是不通过的,因为elementData的容量已经是10了,而size并不是10,所以不会走判断,而是直接把我们的数据添加到数组的最后一个位置,并让size + 1。那么我们看一下要是数组的容量已经满了达到了10,我继续添加会怎么样子?

这里size = 10 elementData.length = 10,说明,目前数组中的容量已经满了,那么就会走grow方法

size + 1 = 11 ,来到grow方法中,minCap = 11,oldCap = 10 ,走判断 oldCap > 0 满足那么就直接进到判断里中,里面可以看到,创建了一个新的长度,并且是1.5倍,那么newCap 就是15,并且Copy了原来的elementData,并且重新给了容量15,返回给了elementData,完成了扩容


完成扩容后,将我们的信息11放到了数组的最后,size + 1

如果我们在创建数组的时候就给了容量会怎么样?只要你给容量不小于0,那么就会在构造的时候直接创建一个有容量的数组。

ArrayList底层的达成原理是什么?
底层是用一个动态数组完成的
初始容量为0,当第一次添加数据的时候才会初始化容量为10
在进行扩容的时候,是原来的1.5倍,每次扩容都需要拷贝数组
在添加数组的时候是有逻辑的
- 确保数组的长度+1之后能够存放当前数据
- 计算数组容量,如果当前已使用的数组长度+1大于当前数组的长度,那么就会调用grow进行扩容1.5倍
- 确保新增的数据有地方存储后,将新的元素添加到位于size位置上
- 返回布尔值
ArrayList list = new ArrayList(10)扩容了几次?
声明和实例了一个数组,指定了容量为10就是一次都没有扩容,这个语句只
浙公网安备 33010602011771号