欢迎,我正在用java小程序编写一个简单的RPG游戏。它变得越来越复杂,许多错误被扔到我的脸上。今天我对.remove();
方法有问题。
Exception in thread "AWT-EventQueue-1" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.remove(Unknown Source)
at rpg.main.paint(main.java:365)
at rpg.main.update(main.java:331)
at sun.awt.RepaintArea.updateComponent(Unknown Source)
at sun.awt.RepaintArea.paint(Unknown Source)
at sun.awt.windows.WComponentPeer.handleEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
这就是错误日志的样子。程序代码:
主.java
正如我们所看到的,在程序结束时油漆中出现了错误,但我不知道可能是由于程序开始时的错误启动引起的?
public void initLocatables()
public void initLocatables2()
我不得不承认它们是在运行方法中的主循环中调用的。这些是错误出现的地方,在下面的评论中,我包括了以前的方法,该方法也引发了错误,两者都remove();
for (Iterator i = locatablesArray.listIterator(); i.hasNext();) {
Locatable l = (Locatable) i.next();
l.draw(g);
i.remove();
}
/*while(itrLocatables.hasNext())
{
Locatable l = itrLocatables.next();
l.draw(g);
l.remove();
}*/
感谢您的任何回复。
也许当你在run()
中调用repaint()
时,paint()
被排队到 EDT 并尽快调用; 在迭代locatablesArray
调用run()
中的initLocatables2()
时,另一次完成,同时重新初始化locatablesArray
,paint()
代码将产生错误。
我的建议是将 init 操作分离到特定的 init 部分中并调用它一次,运行您的主循环。
只是另一件事:你为什么要在initLocatables2()
中初始化一个Iterator
(类字段itrLocatables
(?如果可能,在需要时使用迭代器。
希望说清楚,英语不是我的母语。
对象时,无法从列表/映射中删除对象。这就是ConcurrentModificationException
的原因
i.remove();
如果要绘制所有可定位元素,然后清除集合,也许应该先绘制所有元素,然后清除集合,而不是动态删除它们。
for (Iterator i = locatablesArray.listIterator(); i.hasNext();) {
Locatable l = (Locatable) i.next();
l.draw(g);
}
// Clear everything from the list
locatablesArray.clear();
java.util.ConcurrentModificationException 另一种方法是使用 for 循环通过 locatablesArray 从末尾开始而不是从开头开始。 这样,删除的任何元素都不会更改数组中尚未扫描的元素的位置。