在 Java 中使用嵌套 for 循环时避免 ConcurrentModificationException

Avoiding ConcurrentModificationException when using nested for-loops in Java

在我的程序中,我创建了团队(例如足球),现在我想创建一种方法,让每个团队都与所有其他团队进行比赛。我的方法抛出 ConcurrentModificationException。这是:

public void playMatches(){
    for (Team team : mTeams) {
        mTeams.remove(team);
        for (Team team1 : mTeams) {
            match(team, team1);
        }
        mTeams.add(team);
    }
}

我正在从 mTeams 中删除团队本身,这样它就不会与自己对战,但这会引发异常。我该如何处理?

当您尝试修改 Collection 时抛出 ConcurrentModificationException 并在其上迭代而不使用迭代器的删除方法。

当您使用语法

for (Team team : mTeams) {

已为您创建一个迭代器。

如果您想从代码中删除项目,您明确需要迭代一个迭代器,或者您需要使用旧式 for 循环进行循环。 例如

for (int i = 0; i < mTeams.size(); i++) {

    // Here you can use add and remove on the list without problems
}

或(但在这里没有用,因为您还需要添加元素,而不仅仅是删除它们)

Iterator<Team> iterator = mTeams.iterator();
while (iterator.hasNext()) {
    Team team = iterator.next());
    // Here you can use iterator.remove but you can't add
}

既然您似乎明白发生了什么,让我们考虑一下您问题的 "how to handle" 部分。好消息是您根本不需要修改 collection。

与其通过删除然后添加项目来修改 collection,不如在内部循环中调用 match 时从外部循环中跳过团队,如下所示:

for (Team team : mTeams) {
    for (Team team1 : mTeams) {
        if (team.equals(team1)) continue;
        match(team, team1);
    }
}

您不能在迭代时对列表进行结构性(add/remove)更改。它会抛出 ConcurrentModificationException。使用迭代器删除或添加