可以擦除for()循环中的ArrayList元素吗?

时间:2013-08-22 11:57:37

标签: java arraylist iterator

我有这段代码:

outlet是传递给该方法的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出口删除“item”会产生错误:

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中不需要的元素。

提前感谢您的帮助,

的Riccardo

9 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:3)

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

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

答案 2 :(得分:1)

使用“for each”循环无法删除。您可以使用Iterator而不是它。

答案 3 :(得分:1)

for (int[] item: outlets) {}

这是一个高级for循环。在内部,它与创建集合的迭代器并迭代它完成相同的事情。但是如果你明确地没有得到一个Iterator对象,你就失去了从集合中删除元素的能力,因为如果你试图在迭代器迭代它时从集合中删除一个元素,你将总是得到java.util.ConcurrentModificationException

所以在你的情况下,outlets.iterator();得到一个迭代器并使用它的删除方法iterator.remove();

最好只使用高级循环进行读取操作。

答案 4 :(得分:1)

由于itreator的失败快速行为而面临的例外情况。 每个前进for循环I.e将为您创建itreator,它始终使用当前大小检查原始大小,当未命中匹配发生时,它将通过您的异常。

根据您的问题,您可以删除每个的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));
}

p.s这里l是你List

但是如前所述,使用itreator remove方法进行此类操作是一种很好的做法。

答案 5 :(得分:0)

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

尝试:

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

    ...

    outletsIterator.remove();
}

注意:不建议混合泛型和数组。考虑使用:List<List<Integer>>

答案 6 :(得分:0)

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

  1. 使用iterate()的{​​{1}}方法获取Collection interface

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

  2. 使用Iterator的{​​{1}}方法获取iterate()     代表你的

    收集,然后遍历它并通过复制

    标记要删除的所需项目

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

    致电Collection interface

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

    复制所需的项目

    通过将列表迭代到新列表并在迭代后调用方法为

    Iterator了解更多详情,请参阅here

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

答案 7 :(得分:0)

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

  1. 您可以跟踪要删除的项目的索引,然后在完成迭代后将其删除。
  2. 或者,您可以在迭代时将所有要保留的内容复制到新列表中,然后在完成后放弃旧列表。
  3. 来源:Getting a ConcurrentModificationException thrown when removing an element from a java.util.List during list iteration?(hvgotcodes)

    1. 使用toArray()出口上的ArrayList功能,对阵列进行迭代,然后从ArrayList个网点删除。

答案 8 :(得分:0)

此处已有很多评论可以解决您的问题。我宁愿看到代码中可能存在的潜在问题。例如,如果只检查索引0和1,为什么要在循环中检查。所以你甚至不需要迭代和删除元素。 对于解决方案,yes iterator是这样做的一种方式,但我更愿意使用google collection API。这种呼叫的例子是

Iterables.filter(yourCollectionToBeFiltered,predicate)

您可以在https://code.google.com/p/guava-libraries/

上进一步探索