6

我正在测试Java(SE7)如何int通过以下代码处理超过其最大值的问题:

int index = 2147483647;//the maximum value of int
long size = 2147483648L; //More than the maximum value of int by 1
int safeCounter=0; //To prevent the infinite loop
while (index<size)
{
    System.out.println("Index now is : "+index);//show the int value
    index++; //increment the int value
    safeCounter++; //increment the number of desired loops
    if (safeCounter==3){
        break;//to break the loop after 3 turns
    }

}

我得到的是:

现在的索引是:2147483647 现在的索引是:-2147483648 现在的索引是:-2147483647

因此,在对此感到困惑之后,(如果我不使用safeCounter它,它将永远在最大值和最小值之间运行int——并且不会抛出异常)我想知道如何ArrayList处理元素数量超过最大值int(假设堆空间不是问题)?如果ArrayList不能处理,还有其他数据结构可以吗?


你能解释一下我从int变量中得到的行为吗?

4

4 回答 4

6

ArrayList 可以包含比 int 的最大值更多的元素吗?

在实践中没有。ArrayList 由单个 Java 数组支持,数组的最大大小为Integer.MAX_VALUE.

(假设,Oracle 可以在不破坏用户代码的情况下重做ArrayList使用数组数组的实现。但他们这样做的机会非常小。)

ALinkedList可以处理内存中可以表示的尽可能多的元素。或者您可以实现自己的列表类型。实际上,您甚至可以实现一个列表类型,它可以容纳比内存中存储更多的元素……如果您的列表实际上是一个生成器,甚至可以实现无限数量的元素。

size()返回结果(等等)的事实实际上int并不是障碍。List API 规范处理了这种异常情况。


您的代码的行为得到了简单的解释。Java 中的整数运算有静默溢出。如果将整数类型的最大正值加 1,它会回绕到最大的负值;即 MAX_VALUE + 1 == MIN_VALUE ...对于整数类型。

于 2013-01-18T05:23:07.117 回答
3

ArrayList 无法处理。arraylist 大小的最大限制是 Integer.MAX_VALUE。您可以使用 LinkedList 可以包含任意数量的元素(实际上取决于您的内存):-)

于 2013-01-18T05:16:52.610 回答
2

来自ArrayList.java

     **
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer.
     */
     private transient Object[] elementData;

由于它在实现中使用数组,因此您不能索引超出Integer.MAX_VALUE,因此这是一个限制。

对于int行为,你可以看看这个问题。

于 2013-01-18T05:24:41.950 回答
1

这是因为 Java 使用有符号整数。ArrayList 索引从 0 开始,无法为 ArrayList 提供负索引。

解决您的问题的一种可能方法是,首先将无符号整数转换为有符号整数,然后在 ArrayList 中使用它。

您可以使用以下代码段将有符号转换为无符号:

public static long getUnsigned(int signed) {
    if(signed > 0) return signed;
    long signedVal = (long)(Math.pow(2, 32)) + signed;
    return signedVal;
}
于 2013-01-18T05:29:17.043 回答