ArrayList()//会使用长度为零的数组 ArrayList(int initialCapacity)//会使用指定容量的数组 public ArrayList(Collection<?extends E>c>//会使用c的大小作为数组容量
假设我们设置一个列表的最初容量为10,如下所示:
ArrayList<Integer> arrayList=new ArrayList<>(10);
使用add方法时,触发的扩容机制:
add(Object o)首次扩容为10,再次扩容为上次的1.5倍
那么当我们给该列表中添加一个元素时,如下所示:
随着我们一直添加,直到该列表存放不下,此时会发生,如下所示:
我们继续添加,此时的容量又无法满足了,继续扩容,但此时的容量大小为15,如果扩容为原来的1.5倍,是不是代表最终容量大小为22.5?
事实并非如此,其容量计算是这样的,先将当前的容量大小右移求出它的一半,再将所得的一半值与当前大小相加
15>>1 7 7+15 22
因此第二次扩容的最终容量大小为22
ArrayList前20次扩容规律如下:
使用addAll方法时,触发的扩容机制:
addAll(Collection c)//没有元素时,扩容为Math.max(10,实际元素个数),有元素时为Math.max(原容量1.5倍,实际元素个数)
当最初容量为0时:
例一:
输出的容量大小为10
例二:
输出的容量大小为11
上述的输出结果让我们很疑惑,为什么不是我们所想的15呢?原因是使用addAll方法时,它在扩容时,当原始容量不够时,它会将下次一定扩容后的容量大小与当前添加元素的个数进行对比,取较大值,例二中的原始容量为0,扩容后的容量为10,但是添加的元素个数为11个,因此,最终的容量大小为11
例三:
由于已存在了10个元素,那么此时容量大小为10,再使用addAll方法进行元素添加时,将扩容的大小为15,添加三个元素后的大小为13,最终的容量大小为15,如下所示:
例四:
由于已存在了10个元素,那么此时容量大小为10,再使用addAll方法进行元素添加时,将扩容的大小为15,添加三个元素后的大小为16,最终的容量大小为16,如下所示: