1

I have this code:

outlets is a ArrayList passed to the method; riverBasin is a 2D "matrix" of 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;
    }
}

removing the "item" from the ArrayList outlets generate an error:

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)

which I do not really completely understand. I suspect, however, that I broke the iterator. Correct ? How could then I remove the unwanted elements in the ArrayList.

Thank you in advance for any help,

riccardo

4

9 回答 9

4

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

于 2013-08-22T12:00:13.303 回答
3

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

final Iterator<int[]> iterator = outlets.iterator();
while (iterator.hasNext()) {
    final int[] item = iterator.next();
    ....
    if (...) {
        iterator.remove();
    }
}
于 2013-08-22T12:00:47.740 回答
1

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

于 2013-08-22T12:01:59.500 回答
1
for (int[] item: outlets) {}

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

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

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

于 2013-08-22T12:05:53.917 回答
1

由于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));
}

ps这里lList你的。

但一如既往地建议,使用itreator remove方法进行此类操作是一种很好的做法。

于 2013-08-22T12:41:31.133 回答
0

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

  1. 使用iterate()of 方法Collection interface获取Iterator 表示

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

  2. 使用iterate()方法Collection interface来获得一个Iterator 代表你的

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

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

    称呼remove(Collection c)

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

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

    your_list_object.remove(new_list_object) 有关更多详细信息,请参见此处

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

于 2013-08-22T12:14:18.780 回答
0

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

Iterables.filter(yourCollectionToBeFiltered, 谓词)

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

于 2013-09-09T08:34:33.897 回答
0

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

尝试:

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

    ...

    outletsIterator.remove();
}

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

于 2013-08-22T12:03:38.170 回答
0

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

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

来源:在列表迭代期间从 java.util.List 中删除元素时抛出 ConcurrentModificationException?(hvgotcodes)

  1. 在您的网点上使用该toArray()功能ArrayList,对数组进行迭代并从您的ArrayList网点中删除。
于 2013-08-22T12:15:15.163 回答