我正在尝试使用迭代器从数组列表中删除项目,并且我继续获取ConcurrentModificationException
这是我的代码:
public void forward()
{
for (Sprite s : sprites)
{
s.move();
for (Iterator<Sprite> iter = sprites.iterator(); iter.hasNext();)
{
s = iter.next();
if (s instanceof Attacker)
{
for (Sprite s2 : sprites)
{
if(s.overlaps(s2))
s2.hit();
}
}
if (s.shouldRemove())
iter.remove();
}
}
}
它适用于大约前15到20次,然后我每次点击都会收到错误
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at Model.forward(Model.java:46)
at Controller.mousePressed(Controller.java:29)
at java.awt.Component.processMouseEvent(Component.java:6522)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6290)
at java.awt.Container.processEvent(Container.java:2234)
at java.awt.Component.dispatchEventImpl(Component.java:4881)
at java.awt.Container.dispatchEventImpl(Container.java:2292)
at java.awt.Component.dispatchEvent(Component.java:4703)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4530)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
at java.awt.Container.dispatchEventImpl(Container.java:2278)
at java.awt.Window.dispatchEventImpl(Window.java:2739)
at java.awt.Component.dispatchEvent(Component.java:4703)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:719)
at java.awt.EventQueue$4.run(EventQueue.java:717)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
我不完全确定哪一个会抛出错误
答案 0 :(得分:2)
你得到一个ConcurrentModificationException
因为你在迭代那个集合时从集合中删除了一个元素,而不是通过迭代器。在这种情况下,您没有外部迭代的显式迭代器,因此无法安全地修改循环内的sprites
集合。
你可以做的最好的事情就是收集要删除的元素到一个临时集合中,然后在循环之后将它们全部删除,如下所示:
Set<Sprite> toRemove = new HashSet<Sprite>();
for (Sprite s1 : sprites) {
if (toRemove.contains(s1)) {
continue;
}
s1.move();
for (Sprite s : sprites) {
if (toRemove.contains(s)) {
continue;
}
if (s instanceof Attacker) {
for (Sprite s2 : sprites) {
if (toRemove.contains(s2)) {
continue;
}
if(s.overlaps(s2)) {
s2.hit();
}
}
}
if (s.shouldRemove()) {
toRemove.add(s);
}
}
}
sprites.removeAll(toRemove);