我正在浏览如何创建自己的列表并登陆此网站http://www.vogella.com/tutorials/JavaDatastructureList/article.html,他们使用以下方法。
private void ensureCapa() {
int newSize = elements.length * 2;
elements = Arrays.copyOf(elements, newSize);
}
我在许多其他网站上发现了类似的方法,并了解了EnsureCapacity的功能。但我不明白为什么长度乘以2(elements.length * 2)。是否有特定原因或是否因数据类型而异?
提前致谢。
答案 0 :(得分:4)
由于某些原因,列表完成后容量加倍。
正如@jheimbouch和@ user3437460所述,它直观地说得有点道理。您希望以与当前列表大小成比例的数量增加它。每次在最后添加一些固定元素可能最终对于一个大胖子列表来说真的很糟糕。
总的来说,效率更高。如果你不清楚你的列表的大小(就像设计你自己的基于数组的列表类一般使用时),如果你每次加倍列表的大小,那么平均在每个大插入集上,每个插入将花费777
恒定时间(这称为分摊常量时间操作)。
考虑一下,调整数组大小的成本是O(1)
。因此,我们唯一可以调整的是我们经常这样做的频率。我们越经常这样做,我们的数组与实际数据大小绑定得越紧密,因此我们消耗更少的内存。我们做的次数越少,我们就可以节省CPU周期。
关于时间复杂性的证据比比皆是,但是我很快就找到了http://anh.cs.luc.edu/363/notes/06A_Amortizing.html
长话短说,在一般情况下它在数学上是合理的,并且在内存消耗和处理时间之间取得了非常好的平衡。
答案 1 :(得分:1)
这是一种常见做法,因此无需一直复制数组。
例如,如果它是elements.length + 1
,则每次添加元素时都会复制到新数组。
简而言之,它是任意的,您可以通过您选择的任何方式增加尺寸。
答案 2 :(得分:0)
但我不明白为什么长度乘以2(elements.length * 2)。是否有特定原因或是否因数据类型而异?
您不希望将大小增加一个固定值,例如5.将基于您当前元素数量的容量加倍到一定程度可确保效率(这样您就不必执行数组一直复制。)
想象一下,你有1000个元素并且它现在已经满了,加倍它是合乎逻辑的,因为它可能有另外1000个元素进入。但是如果你用固定值添加容量,你可能会添加太多能力还是太少。
当你添加太多时,你就是在浪费内存,但如果添加的很少,你可能需要过于频繁地执行另一次数组复制,这不是很有效,因为这意味着你更有可能调整添加新元素时的当前数组。