ArrayList实现了List接口它是一个可调整大小的数组可以用来存放各种形式的数据。并提供了包括CRUD在内的多种方法可以对数据进行操作但是它不是线程安全的,ArrayList按照插入的顺序来存放数据。
通过源码分析 ArrayList 的扩容机制
通过以上,可以发现以无参数构造方法创建 ArrayList 时,实际上初始化赋值的是一个空数组。当真正对数组进行添加元素操作时,才真正分配容量。即向数组中添加第一个元素时,数组容量扩为10
具体的扩容机制
-
初始化ArrayList时,会创建一个默认长度的内部数组作为容器,通常默认长度是10。
-
当向ArrayList中添加元素时,如果当前元素数量小于容量(内部数组的长度),直接将元素添加到数组末尾。
-
当添加元素时,如果当前元素数量等于容量,则会进行扩容操作。扩容操作会创建一个新的长度更大的数组,然后将旧数组中的元素复制到新数组中。
-
新数组的长度通常是原数组长度的1.5倍(在JDK1.7及之前是原数组长度的1.5倍,JDK1.8及之后则变为原数组长度的1.5倍再加1)。
-
复制元素到新数组后,旧数组会被丢弃并被垃圾回收。
总结
在JDK1.8中,如果通过无参构造的话,初始数组容量为0,当真正对数组进行添加时(即添加第一个元素时),才真正分配容量,默认分配容量为10;当容量不足时(容量为size,添加第size+1个元素时),先判断按照1.5倍(位运算)的比例扩容能否满足最低容量要求,若能,则以1.5倍扩容,否则以最低容量要求进行扩容。
执行add(E e)方法时,先判断ArrayList当前容量是否满足size+1的容量;
在判断是否满足size+1的容量时,先判断ArrayList是否为空,若为空,则先初始化ArrayList初始容量为10,再判断初始容量是否满足最低容量要求;若不为空,则直接判断当前容量是否满足最低容量要求;
若满足最低容量要求,则直接添加;若不满足,则先扩容,再添加。