【问题标题】:Why does this code throw an IndexOfOutBoundsException - aka, what's up with ensureCapacity()?为什么这段代码会引发 IndexOfOutBoundsException - 也就是 ensureCapacity() 是怎么回事?
【发布时间】:2009-10-29 15:57:46
【问题描述】:

考虑以下两个sn-ps代码:

int index = 676;
List<String> strings = new ArrayList<String>();
strings.add(index, "foo");

int index = 676;
List<String> strings = new ArrayList<String>();
strings.ensureCapacity(index);
strings.add(index, "foo");

在第一种情况下,看到 IndexOfOutBoundsException 我并不感到惊讶。 According to the APIadd(int index, E element) 将抛出 IndexOfOutBoundsException “如果索引超出范围 (index &lt; 0 || index &gt; size())”。 strings 的大小在添加任何元素之前为 0,因此 index 肯定会大于 ArrayList 的大小。

但是,在第二种情况下,我希望对ensureCapacity 的调用会增长strings,这样对add 的调用就会在索引676 处正确插入字符串"foo" - 但事实并非如此。

  1. 为什么不呢?

  2. 我应该怎么做才能让add(index, "foo")index &gt; strings.size() 工作?

【问题讨论】:

    标签: java arraylist


    【解决方案1】:

    ArrayList 中底层数组的容量与更高级别的 List API 方法(添加、删除等)不同,并且只涉及支持数组的大小。如果您想允许添加超出列表边界的元素,您需要在实用程序类中自己编写代码(或找到一个为您执行此操作的集合),填充空值、空对象或您的应用程序在新对象之间期望的任何内容索引和旧大小。

    【讨论】:

    • 这是正确答案。出于性能原因,存在ensureCapacity() 方法。在某些情况下,允许ArrayList 在添加新元素时自动调整后备数组的大小可能会很慢,因为每次新列表长度超过后备数组的长度时都必须重新分配数组。使用ensureCapacity(),您可以说“我将拥有至少 N 个元素,所以从 N 个元素的支持数组开始。”
    【解决方案2】:

    ArrayList.ensureCapacity() 不会改变列表的实际大小(由 size() 返回),而是重新分配内部缓冲区,这样它就不需要重新分配缓冲区来增长到这个大小(当你调用 list.add(object)。

    /**
     * Increases the capacity of this <tt>ArrayList</tt> instance, if
     * necessary, to ensure that it can hold at least the number of elements
     * specified by the minimum capacity argument.
     */
    

    【讨论】:

      【解决方案3】:

      大胆猜测,我认为您正在寻找的是

      Integer index = Integer.valueOf(676);
      Map<Integer,String> strings = new HashMap<Integer,String>();
      strings.put(index, "foo");
      

      【讨论】:

      • 有趣的是你应该提到这一点。我开始使用地图,在我漫长的一天的编码过程中,模糊的思维最终切换到了列表(昨晚)。在实现调整列表大小大约一半后,我刚刚切换回地图。
      【解决方案4】:

      你的长度是 676,但你必须记住它们是从零开始的,所以实际上,你希望索引 -1 是你的最大数字。

      【讨论】:

        猜你喜欢
        • 2018-06-20
        • 2022-07-18
        • 1970-01-01
        • 2018-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多