ConcurrentModificationException在使用Iterator<Node>时发生。

huangapple go评论121阅读模式
英文:

ConcurrentModificationException while using Iterator<Node>

问题

I was trying to delete a row of JavaFX GridPane with JavaFX Rectangles and I found no way to do so but copying the squares above to one row below. Here is my code to do that but it keeps throwing ConcurrentModificationAcception.

static void copyAbove(int rowToBeDisappear, GridPane mainGrid) {
        for (int y = (rowToBeDisappear-1); 0 &lt;= y ; y--) {
            for (int x = 0; x &lt;= 9; x++) {
                Iterator&lt;Node&gt; 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));
                    }
                }
            }
        }
    }

The error

>Caused by: java.util.ConcurrentModificationException
at com.sun.javafx.collections.VetoableListDecorator$VetoableIteratorDecorator.checkForComodification(VetoableListDecorator.java:714)
at com.sun.javafx.collections.VetoableListDecorator$VetoableIteratorDecorator.hasNext(VetoableListDecorator.java:682)
at Main.copyAbove(Main.java:%local_code_row_nvm_this%)

英文:

I was trying to delete a row of JavaFX GridPane with JavaFX Rectangles and I found no way to do so but copying the squares above to one row below. Here is my code to do that but it keeps throwing ConcurrentModificationAcception.

static void copyAbove(int rowToBeDisappear, GridPane mainGrid) {
        for (int y = (rowToBeDisappear-1); 0 &lt;= y ; y--) {
            for (int x = 0; x &lt;= 9; x++) {
                Iterator&lt;Node&gt; 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));
                    }
                }
            }
        }
    }

The error

>Caused by: java.util.ConcurrentModificationException
at com.sun.javafx.collections.VetoableListDecorator$VetoableIteratorDecorator.checkForComodification(VetoableListDecorator.java:714)
at com.sun.javafx.collections.VetoableListDecorator$VetoableIteratorDecorator.hasNext(VetoableListDecorator.java:682)
at Main.copyAbove(Main.java:%local_code_row_nvm_this%)

答案1

得分: 3

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

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

如果getSqrByIndex()保证在给定xy时最多返回一个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);
}

请注意,这是您的原文内容的翻译。

英文:

Thanks to @Slaw for pointing out the flaw in my solution.

You can't iterate an iterator and modify its backing collection (except through that iterator's remove method) at the same time. Store any structural changes you'd like done on the collection to a temporary collection, then perform them after iterating.

If getSqrByIndex() is guaranteed to return at most one Node given an x and a y, then the following code will not cause CMEs:

Node node = null;

Iterator&lt;Node&gt; 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

得分: 0

我是一个完全的白痴,对这一点一窍不通,所以可能是错的,但为什么不使用for()循环而不是while()呢?我认为它可以保持在范围内,这样你就可以调用iterater.remove()。此外,它可能会抛出异常,因为你在迭代的同时正在向迭代器中添加对象。我建议尝试分开添加和删除对象的点。

英文:

I’m a total idiot and new to this so this may be wrong, but why not use a for() loop instead of while()? I believe it keeps it in scope so that you can call iterater.remove(). Also, it may be throwing that because you’re adding objects into your iterator at the same time that you’re iterating. I would try separating the points in which you add and remove objects.

huangapple
  • 本文由 发表于 2020年7月28日 12:42:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/63127160.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定