嵌套迭代遍历列表,然后是最终删除

我试图通过循环遍历列表(嵌套循环)迭代。 考虑以下代码:

ArrayList list = new ArrayList(); // add some values to it for(int i : list) { // ConcurrentModificationException Iterator iterator = list.iterator(); while(iterator.hasNext()) { int n = iterator.next(); if(n % i == 0) { iterator.remove(); } } } 

上面的示例导致ConcurrentModificationException。 当然,移除元素的条件只是一个例子。

我确定我只是遗漏了一些东西; 但是我应该如何构建一个在Java 中实现相同function而不会抛出exception的循环

当你迭代它导致execption时,显然修改了list 。 您可以使用另一个列表来维护要删除的元素列表,并在最后删除它们。

 ArrayList list = new ArrayList(); // add some values to it ArrayList del = new ArrayList(); // Elements to be deleted for(int i : list) { // ConcurrentModificationException Iterator iterator = list.iterator(); while(iterator.hasNext()) { int n = iterator.next(); if(n % i == 0) { del.add(n); } } } list.removeALL(del); 

使外部迭代迭代列表的副本。

 for (int i : new ArrayList<>(list)) { Iterator iterator = list.iterator(); while (iterator.hasNext()) { int n = iterator.next(); if (n % i == 0) { iterator.remove(); } } } 

您正在获取ConcurrentModificationException因为在执行for循环时您正在尝试修改list

我不确定以下是否是优雅的解决方案,但下面的内容可能有效:

  Iterator iterator = list.iterator(); int i=1; while (iterator.hasNext()) { int n = iterator.next(); if (n % i == 0) { iterator.remove(); } i++; } 

您无法从正在迭代的列表中删除项目。 一种选择是将您需要的项目添加到另一个列表中。 最后,您列出了您需要的物品。 或者您可以迭代原始列表的克隆。

我做了一些与你非常相似的事情。 哈哈对这段代码说。

 out:for(int h=0; h 

我想你也可以在从arraylist中删除元素后更改索引。

我没试过,但要么使用:

 List list = new ArrayList(); // add some values to it for(Iterator iterator1 = list.iterator(); iterator1.hasNext();) { int i = iterator1.next(); for(Iterator iterator2 = list.iterator(); iterator2.hasNext();){ int n = iterator.next(); if(n % i == 0) { iterator2.remove(); } } } 

或者如果这仍然抛出ConcurrentModificationException(我不确定如果你使用由同一列表支持的2个迭代器会发生什么),那么使用:

 List list = new ArrayList(); // add some values to it for(int i : new ArrayList(list)){ // copy list ... } 

foreach java语法隐藏了一个迭代器但是隐藏它,就不可能在这个上调用remove方法。

所以我会这样做:

 ArrayList list = new ArrayList(); // add some values to it int count = 0; for(Iterator it = list.iterator();it.hasNext();count++){ //increments count++ Integer currentInt = it.next(); if(currentInt % count == 0){ it.remove(); } } 

您可以看到,无需二级迭代器即可实现相同的function。

您无法在同一时间迭代同一列表。 总而言之,每当列表被平行更改或迭代时, modcount变量用于检测其自身的意外更改。 因此导致ConcurrentModificationException 。 它经常出现在multithreading环境中,开发人员必须意识到这一点。

此外,更喜欢使用循环而不是循环迭代集合。

为什么?

因为使用while方式,在循环之后让迭代器对象仍然在范围内,而对于for ,它不会。 对it.next()一个简单的ackward调用最终会出现NoSuchElementException

保持最好的做法;)