【问题标题】:Can an ArrayList contain more elements than the maximum value of int?ArrayList 可以包含比 int 的最大值更多的元素吗?
【发布时间】:2013-01-01 19:13:31
【问题描述】:

我正在通过以下代码测试 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 变量中得到的行为?

【问题讨论】:

标签: java arraylist integer max heap-memory


【解决方案1】:

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

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

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

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

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


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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 实际上有点明显,考虑到size() 和类似的函数都是用整数声明的。
    • 来自文档:“返回此列表中的元素数。如果此列表包含多个 Integer.MAX_VALUE 元素,则返回 Integer.MAX_VALUE”
    • 我从 int 变量中得到的行为呢?不确定我是否理解它,有什么想法吗?
    • 没有错..但是由于ArrayList是由数组支持的,所以我们不能向arraylist添加超过Tnteger.Max_Value的对象。但是在LinkedList的情况下我们可以添加。如果它包含超过Integer .MAX_VALUE 元素,调用 size() 时会返回 Integer.MAX_VALUE
    • @MAK..来自文档“整数运算符不以任何方式指示溢出或下溢”。Integer.MAX_VALUE + 1 == Integer.MIN_VALUE。然后如果我们继续增加它,我们将得到 -2147483647、-2147483646、-2147483645 等(因为我们将负整数加 1)
    【解决方案3】:

    来自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 问题。

    【讨论】:

      【解决方案4】:

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

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

      您可以使用以下 sn-p 将有符号转换为无符号:

      public static long getUnsigned(int signed) {
          if(signed > 0) return signed;
          long signedVal = (long)(Math.pow(2, 32)) + signed;
          return signedVal;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-26
        • 2013-04-01
        相关资源
        最近更新 更多