删除两个索引时的Java ConcurrentModificationException,当前索引和随机索引

标签 java arrays loops exception

我有一份球员名单。 此列表包含没有目标的玩家。 Targets 表示一个玩家针对另一个玩家,他们两个是目标,不应该在列表中。

下面这个循环的目的是遍历所有玩家,寻找目标,如果玩家还没有准备好,就调用tick()方法,基本上勾选目标搜索计时器。 isReady 方法基本上是 timer == 0

    for (Client c : participants) {
        PlayerTargetDomain dom = c.getTarget();
        if (dom.isReady()) {
            if (dom.getSearchDelay() == 0) {
                SharedTargetDomain d;
                if ((d = search(c)) != null) {
                    participants.removeAll(Arrays.asList(d.getFirst(), d.getSecond()));
                    continue;
                }
            }
            else {
                dom.tickSearchDelay();
            }
        }
        else dom.tick();
    }

现在的 search() 方法,基本上是寻找匹配的目标,如果找到,它将构建包含当前索引和找到的目标索引对象的 SharedTargetDomain

如果 search(Client) 返回的 SharedTargetDomain 实例不为空,我将从 participants 列表中删除这两个对象,使用全部移除()

不幸的是,如果我删除其中任何一个,我将收到以下错误:

java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at mod.game.TargetManager.execute(TargetManager.java:24)

第 24 行是这样的:

for (Client c : participants) {

为什么我会收到这个?我已经尝试对当前索引使用迭代器,但我仍然收到错误,因为我也在删除另一个索引,但是如果我删除另一个索引,另一个与当前索引有什么关系呢?我真的误会了什么。

谢谢!

迭代器实现:

    Iterator<Client> itr = participants.iterator();
    while(itr.hasNext()) {
        Client c = itr.next();
        if (c != null) {
            PlayerTargetDomain dom = c.getTarget();
            if (dom.isReady()) {
                if (dom.getSearchDelay() == 0) {
                    SharedTargetDomain d;
                    if ((d = search(c)) != null) {
                        participants.remove(d.getSecond());
                        itr.remove();
                        continue;
                    }
                }
                else {
                    dom.tickSearchDelay();
                }
            }
            else dom.tick();
        }
    }

最佳答案

问题是您在迭代时修改集合。

至少有两种解决方案

  1. 使用索引访问。处理索引会带来很多乐趣,因为元素会在删除后移动。
  2. 收集您需要删除的元素并在完成迭代后应用所有更改,始终牢记您处理的元素可能已经安排删除,您会得到很多乐趣。

关于删除两个索引时的Java ConcurrentModificationException,当前索引和随机索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25627273/

相关文章:

java - JSONAssert - 在指定范围内比较

javascript - JS reduce - 仅对对象中的数组长度求和

javascript - 从对象数组返回名称数组

当变量不满足要求时PHP重复一个函数

javascript - 如何使用 jquery 循环遍历具有嵌套对象的数组?

c++ - 从具有特定字符串长度的 vector 中删除元素

java - 可滚动的选项卡内容

java - 如何在 Spring Boot 中重写InternalResourceViewResolver?

java - 如何在 IDE 之外启动 JavaFX 11 应用程序?

c++ - 从 C++ 函数返回数组