请教各位大佬,我很好奇StringBuilder的扩容时,为什么要将容量设置为原来容量的2倍+2
如下代码
private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
如果使用两倍的话还能减少一次运算?而且+2我也没感觉到太大的用处....请赐教
不是很清楚,可能的原因如下,你看源代码求证吧
(1)默认容量是0
(2)需要一个结束符
(3)内存对齐的需要,提高性能
(4)经验上看,这么做比较好。
这样是为了确保一次就能满足用户所需,如果你进行翻倍之后空间不够的话还需要再次翻倍就会产生多余空间,一般都是稍微保留余地的翻倍。
int newCapacity = (value.length << 1) + 2;
这样是为了确保一次就能满足用户所需
不够的时候会选择自己传过来的长度哦,而且翻倍已经很多了,我不觉得多2是为了空间
我就是想知道为什么要乘2了 为什么还要+2,不想要流程啊,扩容流程我已经看过了.
我就是知道这么设计的用意......谢谢大家
这个你要问的是开发的人员,正常情况下,扩容2倍,效率更好点;
那个是位移运算,>>2之后加2才是两倍,你可以去试一下,
我的意思是如果容器现在为16,你现在添加一个大小为17的字符,触发扩容机制,如果不加2,扩容后是大小为32,但是32是17的两倍吗?我觉得你更应
该纠结为什么要用位移运算,而不是*2.
我也是想到这个问题来找答案的,找到了这也没有答案,但是我想着想着就想出来了。
原因就是它有个带参构造方法:StringBuilder(int capacity);这个参数可以传值0,然后当我要append数据的时候,进行扩容,如果扩容方式是int newCapacity = (value.length << 1),那么它会一直是0,也就无法扩容,无法存放数据并抛错,为了避免这种情况的出现才对扩容*2+2;
因大小可以传入0。
具体原因:传入0,会触发hugeCapacity(),直接就是MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8的容量大小,故+2,防止这种情况。