希望下面的内容对你有所帮助,谢谢!
首先我们直接上图
想必大家看了这个之后明白了扩容的大小吧
对,就是你想的1.5倍,下面是扩容的源码证明(第四行代码)
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
int newCapacity = oldCapacity + (oldCapacity >> 1);// 就是这句
或许这时候你会有疑问,既然是作者说是1.5倍(>> 1 就是 除2 ,也就是0.5倍, 1.5倍 = 1倍 + 0.5倍),那为啥这里的代码有这么多判断呢?
或许聪明的你看到了两个if就已经明白了,这不就是条件判断吗,是的,这是临界状态的判断。
第一个if是当扩大了1.5倍后还容纳不了数组所需的最小容量(这里的minCapacity就是数组所需的最小容量)。例如,现在的数组容量为10,扩容后为15,但是数组所需的最小容量是18,那这个时候肯定不能简单的按1.5倍来扩容了,那按什么容量来呢?那肯定就直接按所需的最小容量18来扩容了。或许这个时候你又有疑问,怎么从10一下子跳到了18啊,不应该是10->11嘛?请先看图(IDEA :按Ctrl + F12 就会出现类的相关信息,然后再搜索关于add的方法)
这是四个添加元素的方法,当你看了第三个方法的时候,我相信聪明的你肯定已经知道了为什么从10一下子跳到了18了,对的,就是你想的那样,往ArrayList中添加了一个集合,所以就有可能10->18了。
第二个if是不能一直扩容下去了,想必这个也很好理解,毕竟容量是有限的,那这里的上限是多少呢?请看下面的源码
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;//2147483639
如果最终的扩容大于这个值,那么最终就会扩容到扩容后的值与Integer.MAX_VALUE两者的最小值,源码如下
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
那如果数组所需的最小容量大于Integer.MAX_VALUE,那超出的元素该怎么办呢?那没办法了,只能丢弃了。
或许看到这里的你想知道这个1.5倍又是如何的实现的呢?请看图
想必聪明的你看完图之后就会明白了所谓的1.5倍的底层是如何实现的了,其实就是创建一个1.5倍容量的新数组,然后把之前的元素都拷贝过去,最后再把新数组赋给原先的数组,这样子就达到了1.5倍的扩容。
感谢你能看到这里,希望上面的讲解对你有所帮助,谢谢!
最后的最后,“嘿,你逆光而来,配得上这世间所有的美好!”