Java 为什么ArrayList通过特定公式扩展elementData数组?

Java 为什么ArrayList通过特定公式扩展elementData数组?,java,arrays,collections,arraylist,Java,Arrays,Collections,Arraylist,就在五分钟前,我发现了ArrayList的工作原理。它有elementData字段,该字段是具有特定类型的数组,如果我们添加了元素并且elementData数组已满,则集合内部通过以下公式创建另一个数组: (oldCapacity * 3) / 2 + 1 并将数据从旧阵列复制到新阵列。我只是想知道,为什么?为什么不把最后的尺码翻一倍呢?通过描述这个公式,我在哪里可以获得更多关于ArrayList集合内部表示的理论信息。 P.S.对不起,我的英语不是我的母语。事实上,增长政策没有具体说明,只是

就在五分钟前,我发现了
ArrayList
的工作原理。它有
elementData
字段,该字段是具有特定类型的数组,如果我们添加了元素并且
elementData
数组已满,则集合内部通过以下公式创建另一个数组:

(oldCapacity * 3) / 2 + 1
并将数据从旧阵列复制到新阵列。我只是想知道,为什么?为什么不把最后的尺码翻一倍呢?通过描述这个公式,我在哪里可以获得更多关于ArrayList集合内部表示的理论信息。
P.S.对不起,我的英语不是我的母语。

事实上,增长政策没有具体说明,只是增加一个元素有一个固定的摊销成本

您提出的方案和JDK使用的方案都提供了这样的保证。事实上,任何乘法增长方案都是合规的。其他语言/库将大小增加了两倍,因此这也是一种常见的方案。不同的Java实现可以选择遵循该方案,并且仍然符合规范


<>参见讨论——关于C++,但同样适用于java。

可能没有客观的度量。我们可以通过浪费更多内存来避免复制,也可以通过更频繁地复制来节省内存。这两个指标不能在一个目标函数中客观地衡量。

加倍将是一个相当大的增长步骤。好吧,加倍是不好的,但为什么是这一个呢?@aacanakin:通过这种方法,每次插入的成本将与列表的大小成正比;因此,例如,从一个空列表开始并插入n个元素将花费O(n²)。这将大大挫败一开始就有数组支持的列表的目的。@aacanakin这个想法是在浪费内存和复制每个列表的次数之间达成合理的折衷。显然,在每次插入时复制列表以避免开销不是一个折衷办法。@aacanakin增长因子小于2的数组支持列表仍然会赢得链表。这是“足够友好的记忆”。(或者更确切地说,是一个以阵列为基础的列表,其容量至少为容量的一半,这应该是常见的情况。)