Java 小程序在从迭代器数组中删除对象时抛出错误



欢迎,我正在用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()时,另一次完成,同时重新初始化locatablesArraypaint()代码将产生错误。
我的建议是将 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 从末尾开始而不是从开头开始。 这样,删除的任何元素都不会更改数组中尚未扫描的元素的位置。

最新更新