【问题标题】:Is possible to erase an ArrayList element inside a for( ) cycle?是否可以在 for() 循环中擦除 ArrayList 元素?
【发布时间】:2013-08-25 03:27:56
【问题描述】:

我有这个代码:

outlets 是传递给方法的 ArrayList; RiverBasin 是 int (int[][] riverBasin) 的二维“矩阵”;

for (int[] item: outlets) {
    if (item[0] < 2 || item[0] > this.riverBasin.length - 1 || item[1] < 2 || item[1] > this.riverBasin[0].length - 1) {

        System.out.println("This provisionally substitutes error catching. Outlet (" + item[0] + "," + item[1] + ") is not correct.");
        outlets.remove(item);
        System.out.println("Remaining outlets: ");
        for (int[] atem: outlets) {
            System.out.print("(" + atem[0] + "," + atem[1] + ")\n");
        }
    }
    else {
        this.riverBasin[item[0]][item[1]] = 10;
    }
}

从 ArrayList 出口中删除“项目”会产生错误:

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
    at java.util.AbstractList$Itr.next(AbstractList.java:343)
    at org.geoframe.ocn.Eden.setMultipleOutlet(Eden.java:135)
    at org.geoframe.ocn.Eden.main(Eden.java:205)

我并不完全理解。但是,我怀疑我破坏了迭代器。 正确的 ?那么我怎么能删除 ArrayList 中不需要的元素。

提前感谢您的帮助,

里卡多

【问题讨论】:

  • 第 1 步:清晰地格式化代码。 (这次我已经为您完成了最基本的操作。)

标签: java arraylist iterator


【解决方案1】:

您应该使用迭代器迭代 ArrayList。然后使用 Iterator 的 remove 方法。

【讨论】:

    【解决方案2】:

    您需要显式使用迭代器并调用 remove()。

    final Iterator<int[]> iterator = outlets.iterator();
    while (iterator.hasNext()) {
        final int[] item = iterator.next();
        ....
        if (...) {
            iterator.remove();
        }
    }
    

    【讨论】:

    • 使用 for 循环而不是 while 循环来最小化迭代器变量的范围。看我的回答。
    • 泛型。我应该使用泛型。演员阵容很糟糕。是的,for() 循环更好。
    【解决方案3】:

    您不能使用“for each”循环来删除。您可以使用 Iterator 代替它。

    【讨论】:

      【解决方案4】:
      for (int[] item: outlets) {}
      

      这是一个高级 for 循环。在内部,它与创建集合的迭代器并对其进行迭代一样。但是,如果您明确没有获得 Iterator 对象,您将失去从集合中移除元素的能力,因为如果您在迭代器对其进行迭代时尝试从集合中移除元素,您将始终得到java.util.ConcurrentModificationException

      因此,在您的情况下,通过 outlets.iterator(); 获取迭代器并使用它的删除方法 iterator.remove();

      最好将高级循环仅用于读取操作。

      【讨论】:

        【解决方案5】:

        由于itreator 的快速失败行为,您面临的异常。 高级 for 循环,即每个循环,将为您创建一个 itreator,它始终检查原始大小与当前大小,当发生未匹配时,它将通过您的异常。

        根据您的问题,您可以使用 for each 删除 Arraylist 元素,
        1-您已经获得要删除的索引或元素,并在循环之外将其删除。

        2-样本:

        for(int i=0;i < l.size() ; i++){
           //some condtions to check the element
           //if you want to delete this element or index
           l.remove(i); or l.remove(l.get(i));
        }
        

        这里lList 你有。

        但一如既往地建议,使用itreator remove 方法执行此类操作是一个好习惯。

        【讨论】:

          【解决方案6】:

          您必须通过迭代器删除条目。这意味着您不能使用增强前循环。

          试试:

          for(Iterator<int[]> outletsIterator = outlets.iterator(); outletsIterator.hasNext();){
              int[] item = outletsIterator.next();
          
              ...
          
              outletsIterator.remove();
          }
          

          注意:不建议将泛型和数组混用。考虑使用:List&lt;List&lt;Integer&gt;&gt;

          【讨论】:

            【解决方案7】:

            已经发布了一些类似的问题和答案:

            1. 您可以跟踪要删除的项目的索引,然后在完成迭代后将其删除。
            2. 或者您可以在迭代时将所有要保留的列表复制到一个新列表中,然后在完成后丢弃旧列表。

            来源:Getting a ConcurrentModificationException thrown when removing an element from a java.util.List during list iteration? (hvgotcodes)

            1. ArrayList 出口上使用toArray() 函数,对数组进行迭代并从ArrayList 出口中删除。

            【讨论】:

              【解决方案8】:

              您不能在迭代集合时直接从集合中删除项目。 要解决您的问题,请使用以下任一解决方案:

              1. 使用Collection interfaceiterate() 方法得到Iterator 代表

                你的集合,然后遍历它并从你的迭代器中删除所需的项目

              2. 使用Collection interfaceiterate() 方法得到Iterator 代表你的

                collection,然后遍历它并通过复制它们来标记要删除的所需项目

                新集合对象中的引用。那么迭代完成后,

                致电remove(Collection c)

                从 Collection 对象中删除所需项目的方法(类似于从

                复制所需项目的方法

                您的列表通过将其迭代到一个新列表并在迭代后调用方法为:

                your_list_object.remove(new_list_object) 了解更多详情,请参阅here)

              来源:https://stackoverflow.com/questions/2513509/how-to-remove-concurrentmodificationexception

              【讨论】:

                【解决方案9】:

                这里已经有很多 cmets 可以解决您的问题。我宁愿看到代码中可能存在的潜在问题。例如,如果它只处理索引 0 和 1,为什么要将 if check 放入循环中。所以你甚至不需要迭代和删除元素。 对于解决方案,迭代器是这样做的一种方式,但我宁愿为此使用谷歌集合 API。这种调用的例子是

                Iterables.filter(yourCollectionToBeFiltered, predicate)

                您可以在https://code.google.com/p/guava-libraries/ 上探索更多内容

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-11-22
                  • 2020-06-08
                  • 2020-06-02
                  • 1970-01-01
                  • 2020-09-21
                  • 1970-01-01
                  • 2019-11-03
                  相关资源
                  最近更新 更多