我正在测试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
变量得到的行为吗?
答案 0 :(得分:4)
ArrayList可以包含的元素多于int的最大值吗?
在实践中没有。 ArrayList由单个Java数组支持,数组的最大大小为Integer.MAX_VALUE
。
(假设,Oracle可以重做ArrayList
的实现来使用数组数组而不会破坏用户代码。但是他们这样做的可能性非常小。)
LinkedList
可以处理在内存中可以表示的任意数量的元素。或者您可以实现自己的列表类型。实际上,你甚至可以实现一个列表类型,它可以容纳比存储在内存中更多的元素......如果你的列表实际上是一个生成器,甚至可以包含无限数量的元素。
size()
返回int
结果(等等)的事实实际上不是障碍。 List API规范处理此异常。
简单解释了代码的行为。 Java中的整数算术具有静默溢出。如果将1加到整数类型的最大正值,它会回绕到最大的负值;即MAX_VALUE + 1 == MIN_VALUE ...表示整数类型。
答案 1 :(得分:3)
ArrayList无法处理.arraylist大小的最大限制是Integer.MAX_VALUE。你可以使用LinkedList,它可以包含任意数量的元素(实际上取决于你的内存): - )
答案 2 :(得分:1)
来自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
行为人,您可以查看this问题。
答案 3 :(得分:1)
这是因为Java使用有符号整数。 ArrayList索引从0开始,无法为ArrayList提供负索引。
问题的一个可能解决方案是,首先将无符号整数转换为signed,然后将n在ArrayList中使用它。
您可以使用以下代码段将签名转换为无符号:
public static long getUnsigned(int signed) {
if(signed > 0) return signed;
long signedVal = (long)(Math.pow(2, 32)) + signed;
return signedVal;
}