【问题标题】:ConcurrentModificationException while using Iterator<Node> [duplicate]使用 Iterator<Node> 时出现 ConcurrentModificationException [重复]
【发布时间】:2020-11-17 11:35:24
【问题描述】:

我试图用 JavaFX 矩形删除 JavaFX GridPane,但我没有办法这样做,只能将上面的方块复制到下面的一行。这是我的代码,但它不断抛出 ConcurrentModificationAcception

static void copyAbove(int rowToBeDisappear, GridPane mainGrid) {
        for (int y = (rowToBeDisappear-1); 0 <= y ; y--) {
            for (int x = 0; x <= 9; x++) {
                Iterator<Node> iterator = mainGrid.getChildren().iterator();
                while (iterator.hasNext()) {
                    Node sqr = iterator.next();
                    if (sqr == getSqrByIndex(x,y,mainGrid)) {
                        iterator.remove();
                        mainGrid.add(sqr,x,(y+1));
                    }
                }
            }
        }
    }

错误

引起:java.util.ConcurrentModificationException 在 com.sun.javafx.collections.VetoableListDecorator$VetoableIteratorDecorator.checkForComodification(VetoableListDecorator.java:714) 在 com.sun.javafx.collections.VetoableListDecorator$VetoableIteratorDecorator.hasNext(VetoableListDecorator.java:682) 在 Main.copyAbove(Main.java:%local_code_row_nvm_this%)

【问题讨论】:

  • iterator 的非并发集合具有fail-fast 机制(如for-each)。
  • 使用ListIterator 允许您在迭代期间添加(通过迭代器)
  • 这闻起来很像 xy 问题(试图删除一行 GridPane),从你的 sparce 描述来看,它看起来就像删除给定行中的所有节点应该做你需要什么。请提供minimal reproducible example 说明您真正 正在努力实现的目标以及没有按预期工作的确切内容。

标签: java javafx iterator gridpane observablelist


【解决方案1】:

感谢@Slaw 指出我的解决方案中的缺陷。

您不能同时迭代一个迭代器并修改其支持集合(通过该迭代器的remove 方法除外)。将您希望对集合进行的任何结构更改存储到临时集合中,然后在迭代后执行它们。

如果在给定xy 的情况下保证getSqrByIndex() 最多返回一个Node,则以下代码不会导致CME:

Node node = null;

Iterator<Node> iterator = mainGrid.getChildren().iterator();
while (iterator.hasNext()) {
    Node sqr = iterator.next();
    if (sqr == getSqrByIndex(x,y,mainGrid)) {
        node = sqr;
    }
}

if (node != null) {
    mainGrid.getChildren().remove(node);
    mainGrid.add(node, x, y + 1);
}

【讨论】:

  • 谢谢,这工作...
【解决方案2】:

我是个彻头彻尾的白痴,所以这可能是错误的,但为什么不使用 for() 循环而不是 while() 呢?我相信它将它保持在范围内,以便您可以调用 iterator.remove()。 另外,它可能会抛出这个问题,因为您在迭代的同时将对象添加到迭代器中。我会尝试分离添加和删除对象的点。

【讨论】:

  • 在这种情况下,循环的类型无关紧要。问题在于以 Iterator#remove() 以外的方式修改迭代器的源。
猜你喜欢
  • 2018-01-09
  • 2013-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-14
  • 2020-11-30
  • 1970-01-01
  • 2011-07-05
相关资源
最近更新 更多