【问题标题】:IndexOutOfBoundsException even though the elements exist in the arraylistIndexOutOfBoundsException 即使元素存在于数组列表中
【发布时间】:2018-03-28 18:07:23
【问题描述】:

当我尝试一个一个地删除它们时,我在 ArrayList 中有 10001 个元素,我在中途得到 IndexOutOfBoundsException 异常,即在 5000 个元素之后。真不知道为什么。

  public static void main(String[] args) {
    List<Integer> numberArrayList = new ArrayList<>();
    List<Integer> numberLinkedList = new LinkedList<>();

    long start, end;

    start = System.currentTimeMillis();
    for (int i = 0; i < 10_001; i++) {
      numberArrayList.add(i);
    }
    end = System.currentTimeMillis();

    System.out.println("Time taken to insert 10_001 elements in ArrayList: " + (end - start));

    start = System.currentTimeMillis();
    for (int i = 0; i < 10_001; i++) {
      numberLinkedList.add(i);
    }
    end = System.currentTimeMillis();

    System.out.println("Time taken to insert 10_001 elements in LinkedList: " + (end - start));

    /* **************************************************************/
    start = System.currentTimeMillis();
    for (int i = 0; i < 10_001; i++) {
      numberArrayList.remove(i);
    }
    end = System.currentTimeMillis();

    System.out.println("Time taken to remove 10_001 elements from the front in ArrayList: " + (end - start));

    start = System.currentTimeMillis();
    for (int i = 0; i < 10_001; i++) {
      numberLinkedList.remove(i);
    }
    end = System.currentTimeMillis();

    System.out.println("Time taken to remove 10_001 elements from the front in LinkedList: " + (end - start));


  }

上面的程序结果

Time taken to insert 100_001 elements in ArrayList: 2
Time taken to insert 100_001 elements in LinkedList: 1
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 5001, Size: 5000
    at java.util.ArrayList.rangeCheck(ArrayList.java:657)
    at java.util.ArrayList.remove(ArrayList.java:496)
    at collections_jnit.list.ArrayList_vs_LinkedList.main(ArrayList_vs_LinkedList.java:34)

【问题讨论】:

  • 因为您在迭代时删除了元素。中途你已经删除了一半的元素和 bam,现在超出了范围。
  • remove() 将后续剩余元素向下移动一个索引。因此,删除 5000 个元素后,最后一个索引是 5000。
  • 如果您需要删除所有项目,只需使用clear()

标签: java arraylist linked-list


【解决方案1】:

一旦删除 5000 个元素,则意味着 10001-5000 = 5001,因此考虑到从 0 的索引,所以现在索引范围是 05000,因此 5001 除外。

解决方案:如果您想在遍历时从列表中删除项目,那么我建议使用Iterators

Iterator<Integer> itr = numberArrayList.iterator();
while (itr.hasNext()) {
    itr.remove();
}

【讨论】:

  • 如果我们要清除所有 List 为什么我们需要迭代每个项目?我认为List.clear() 是安全的。
  • @MenaiAlaEddine 在这种情况下,OP 正在做一些基准测试(所以我没有建议),尽管clear 使用循环几乎做了同样的事情,尽管它简洁且时间有效跨度>
  • 我没有很深的经验,但我认为我们使用 Iterator 和 removeIf () ..etc,如果我们需要删除一些项目,我的意思是当我们有条件时。
【解决方案2】:

你可以改成while循环:

while (numberLinkedList.size() > 0) {
    numberLinkedList.remove(0);
}

使用 for 循环,您将删除 i 处的对象,这会增加每次迭代,因此您最终只删除了一半的项目。

【讨论】:

    【解决方案3】:

    正如已经回答的那样,为什么您会收到IndexOutOfBoundException,所以我要补充一下,您如何安全地删除所有元素。有两种方法可以做到这一点:

    1. ArrayList.clear()

    2. ArrayList.removeAll()

    这两个方法都从List 继承到ArrayList。 1 比 2 快。

    【讨论】:

      【解决方案4】:

      列表不是数组。 如果您将元素添加到大小为N 的列表中,则列表大小将增加,这意味着您可以访问元素N + 1。如果删除任何元素,则无法访问元素N + 1,该元素将位于N 的位置。

      数组有固定的位置和固定的大小。

      请看文档:

      【讨论】:

        【解决方案5】:

        numberLinkedList.clear();

        或者如果你想迭代,使用 Java 8+ :)

        numberLinkedList.removeIf(i -> true);

        【讨论】:

          猜你喜欢
          • 2017-01-13
          • 2015-02-04
          • 1970-01-01
          • 1970-01-01
          • 2014-01-28
          • 2016-11-05
          • 2022-01-24
          • 1970-01-01
          • 2018-09-17
          相关资源
          最近更新 更多