Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 6和Java 7在ArrayList容量增长方面的差异_Java_Math_Arraylist - Fatal编程技术网

Java 6和Java 7在ArrayList容量增长方面的差异

Java 6和Java 7在ArrayList容量增长方面的差异,java,math,arraylist,Java,Math,Arraylist,我有一个关于如何在Java中管理ArrayList的容量增长(不是大小,而是容量)的问题。 当我们使用默认构造函数初始化ArrayList而不设置容量时,默认情况下容量设置为=10 此时,当我们将另一个元素添加到列表中时,Oracle文档说“当元素添加到ArrayList中时,其容量会自动增长。除了添加元素具有恒定的摊余时间成本这一事实之外,不会指定增长策略的详细信息。” 如果我们看看Java内部,容量增长策略已经改变了它的功能。在Java 6之前,它是: (1) int newCapacity

我有一个关于如何在Java中管理ArrayList的容量增长(不是大小,而是容量)的问题。 当我们使用默认构造函数初始化ArrayList而不设置容量时,默认情况下容量设置为=10

此时,当我们将另一个元素添加到列表中时,Oracle文档说“当元素添加到ArrayList中时,其容量会自动增长。除了添加元素具有恒定的摊余时间成本这一事实之外,不会指定增长策略的详细信息。”

如果我们看看Java内部,容量增长策略已经改变了它的功能。在Java 6之前,它是:

(1) int newCapacity = (oldCapacity * 3)/2 + 1;
从Java 7(和>7)可以看出:

但这两个数学级数略有不同。从默认值(10)开始,我们有:

(1) 10,16,25,38,58,88133200301452

(2) 10,15,22,33,49,73109163244366

我认为这对ArrayList的使用没有任何影响,但是为什么他们要更改这个函数呢?是否存在任何性能原因?他们是否在旧版本中发现了一个缺陷或bug?

OpenJDK显示,它已被in更改以修复bug

新代码小心地避免了不必要的整数溢出<代码>旧容量*3可以溢出,即使
旧容量*3/2
没有溢出。新行
oldCapacity+(oldCapacity>>1)
将不起作用。如果它确实溢出并变为负值,则会有额外的代码将容量设置为
Integer.MAX_VALUE
(或接近它)

值得注意的是,关于摊销时间的任何陈述 添加/插入操作的复杂性,例如
ArrayList中的操作
javadoc,由于与性能相关的bug而失效。一个
解决上述情况的方法是设置
初始大小计算时,将数组备份为
整数.MAX_值
在调整大小期间,结果为负数

(2) int newCapacity = oldCapacity + (oldCapacity >> 1);
/**
 * The maximum size of array to allocate.
 * Some VMs reserve some header words in an array.
 * Attempts to allocate larger arrays may result in
 * OutOfMemoryError: Requested array size exceeds VM limit
 */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

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);
}

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
    newCapacity = minCapacity;