我有一个球员名单。 此列表包含没有目标的玩家。目标意味着玩家被定位到另一个玩家,他们两个是目标,并且不应该在列表中。
以下循环的目的是遍历所有玩家,并搜索目标,如果玩家尚未准备好,它将只调用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
和找到的目标索引对象。
如果SharedTargetDomain
中返回的search(Client)
实例不为空,我将使用participants
removeAll()
列表中删除这两个对象
不幸的是,如果我删除其中任何一个,我将收到以下错误:
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用于当前索引,但我仍然得到错误,因为我也删除了另一个索引,但是如果我删除它,那么另一个与当前索引有什么关系呢?我真的误解了一些事情。
谢谢!
Iterator
实施:
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();
}
}
答案 0 :(得分:3)
问题是你在迭代时修改了集合。
至少有两个解决方案
答案 1 :(得分:0)
您可以使用
CopyOnWriteArrayList以避免此异常