ArrayList
ArrayList 初始容量是多少?
ArrayList 何时触发扩容?
ArrayList 扩容策略是什么?
ArrayList 会缩容吗?(删除元素之后数组会变小吗?)
为什么阿里巴巴规范创建的时候需要指定容量?
ArrarList 的构造
首先,我们先看一下 ArrayList 的无参构造代码。
在调用无参构造的时候,会把内部数据指向DEFAULTCAPACITY_EMPTY_ELEMENTDATA
当中。而DEFAULTCAPACITY_EMPTY_ELEMENTDATA
是一个static final
修饰的变量,所以在类加载的时候就创建了,并且其不可修改。总的来说就是当你不传递参数的时候,内部的数组会指向一个空数组,该数组是由类加载的时候便创建了,且不可修改。如下图所示,DEFAULTCAPACITY_EMPTY_ELEMENTDATA
相当于一个缓冲区的作用。
ArrayList 的有参构造
扩容
当调用add(E o)
的时候,执行过程如下图所示。只有当当前容量超过数组容量的时候,才会进行扩容操作。
如下图所示,展示了计算当前容量的代码,其中 minCapacity
是add()
之前的size+1
,DEFAULT_CAPACITY
即默认大小为10
扩容代码如下图所示
remove
remove(Object o)
首先找到要删除的下标,查找的方式是通过equals()
,然后通过fastRemove(int index)
来进行真正的删除。
通过fastRemove(int index)
的整个过程就是将index
之后的值往前挪一个位置,并将size-1
由于要将最后一个元素置为null
,所以采用的是arraycopy
而不是简单的后一个把前一个覆盖。可以看出整个过程并没有对数组进行缩容操作,所以ArrayList
没有缩容过程。
总结
- ArrayList 初始容量是多少?
和你的构造函数有关,如果采用的是无参构造,初始容量为零,是空数组。(不是null),如果是有参构造,参数为零空数组,参数大于零,那么就会新建一个该参数大小的数组。
- ArrayList 何时触发扩容?
当调用add发现数组容量不够时,就会发生扩容。
- ArrayList 扩容策略是什么?
扩容策略是为原来的 1.5 倍,在
grow()
中进行扩容操作。
- ArrayList 会缩容吗?(删除元素之后数组会变小吗?)
ArrayList 并没有缩容操作,仅仅只是把数组的值改为了
null
,让原来数组里面的对象可以被垃圾回收。
- 为什么阿里巴巴规范创建的时候需要指定容量?
因为扩容操作是为原来的 1.5 倍,比如说我有 10000 个元素,通过扩容以后有 15000, 但是实际上我只使用 10001 个元素,浪费了 4999 个容量空间