1.若以ArrayList的空构造方法去构造对象,此时ArrayList的默认容量是0,只有在使用add()方法时才会开辟空间,并且空间大小为10。
2.在扩容时,ArrayList的长度会以1.5倍进行扩容
3.若以ArrayList的带参构造方法去构造对象,此时ArrayList的容量即输入参数的大小,
若输入的参数x > 0,则ArrayList的长度为x
若输入的参数x == 0,则ArrayList的长度为0,并在使用add方法时才会开辟空间,大小为10
若输入的参数x < 0,则会抛出异常
先给出结论,接下来从java源码的角度去解释这些问题。
注意:确定1.5倍扩容、ArrayList长度置为10都在grow()方法中,
最终操作全是在grow()方法内的copyOf()中进行的
目录
一.使用空构造方法,ArrayList的默认长度为0,只有在使用add()时才会开辟长度为10的空间。
二.再讲一讲1.5倍扩若,还是在grow()中进行1.5倍扩容
一.使用空构造方法,ArrayList的默认长度为0,只有在使用add()时才会开辟长度为10的空间。
1.空构造方法就是让elementData = {};并没有给ArrayList分配空间,此时size为0
2.打开add()源码:ensureCapacityInternal(size + 1);//size为0,参数就是1
3.再打开ensureCapacityInternal();源码
4.接着先打开内部的calculateCapacity()源码
从1中我们了解到,空的构造方法就是让
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
因此4中的if条件成立,会执行内部语句,也就是返回DEFAULT_CAPACITY 和 minCapacity中的最大值,由于DEFAULT_CAPACITY源码默认为10, minCapacity此时为1,所以返回10.
5.此时ensureCapacityInternal();的内部参数为10,接着打开ensureCapacityInternal()下的外部方法ensureExplicitCapacity()
6.由于if条件成立,接着执行grow()方法
7.根据上面数据可以知到,newCapacity会赋值为10,最终调用copyOf()进行扩容,此时ArrayList的长度就是10 了
二.再讲一讲1.5倍扩若,还是在grow()中进行1.5倍扩容
1.扩容的前提是ArrayList中的有效元素个数等 == ArrayList的长度,也就是size == 10,再接着add()时就需要扩容,方法与上述相同我就一张图总结(跟着序号的顺序看)
三.带参构造方法根据输入参数来进行长度的开辟
结论:
若输入的参数x > 0,则ArrayList的长度为x
若输入的参数x == 0,则ArrayList的长度为0,并在使用add方法时才会开辟空间,大小为10
若输入的参数x < 0,则会抛出异常