迭代

时间:2016-10-15 07:15:30

标签: java iteration concurrentmodification

this 可能是最接近我的情况,但这也没有任何帮助。

我在这里得到了ConcurrentModificationException:

for (Iterator<ProjectileBase> iterator = projectiles.iterator(); iterator.hasNext();) {
        ProjectileBase proj = iterator.next();  < here
        if (proj == null || !proj.isValid()) {
            iterator.remove();
            continue;
        }
        if (((!proj.ignoreRange()) ? proj.lived <= proj.data.getRange() : true)){
            proj.lived++;
            proj.onTick();
        } else {
            MissileHitEvent event = new MissileHitEvent(proj.shooter, proj.wand, proj, false, null);
            Bukkit.getPluginManager().callEvent(event);
            if (!event.isCancelled()) {
                iterator.remove();
                continue;
            } else {
                proj.lived = 0;
            }
        }
    }

即使我按建议做了here

列表如下所示:

private List<ProjectileBase> projectiles = new ArrayList<ProjectileBase>();

这是在类构造上初始化的。问题是什么?

编辑:控制台日志:

[10:01:58] [Craft Scheduler Thread - 3754/WARN]: Exception in thread "Craft Scheduler Thread - 3754" 
[10:01:58] [Craft Scheduler Thread - 3754/WARN]: org.apache.commons.lang.UnhandledException: Plugin MagicWands v1.0 generated an exception while executing task 247
    at org.bukkit.craftbukkit.v1_9_R2.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:57)
    at com.destroystokyo.paper.ServerSchedulerReportingWrapper.run(ServerSchedulerReportingWrapper.java:22)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at io.jettymc.DataHolders.ProjectileManager.iterate(ProjectileManager.java:117)
    at io.jettymc.DataHolders.ProjectileManager$1.run(ProjectileManager.java:232)
    at org.bukkit.craftbukkit.v1_9_R2.scheduler.CraftTask.run(CraftTask.java:58)
    at org.bukkit.craftbukkit.v1_9_R2.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:53)
    ... 4 more

编辑2:嗯,我想它值得一说,我在Bukkit / Spigot(Minecraft服务器和API)上构建这个项目..但我怀疑它& #39;是导致此错误的原因吗?

2 个答案:

答案 0 :(得分:1)

为了帮助缩小问题范围,有一个可能有用的技巧。

假设projectilesArrayList的唯一引用,您可以在迭代时暂时将其替换为不可变列表,因此只有Iterator可以修改列表。如果其他一些代码试图修改列表,则会发生异常,应该让您知道它发生的位置,假设您的错误处理没有搞砸。

示例:

List<ProjectileBase> projectilesHold = projectiles;
projectiles = Collections.unmodifiableList(projectiles);
try {
    for (Iterator<ProjectileBase> iterator = projectilesHold.iterator(); iterator.hasNext();) {
        // other code here is unchanged
    }
} finally {
    projectiles = projectilesHold;
}

代码将可修改列表保存在“hold”变量中,然后包装列表以使其不可修改。 finally块将确保恢复可修改列表,无论如何。

然后修改for循环迭代器以使用“hold”中的可修改列表,因此其remove()方法可以正常工作,但projectiles字段的任何其他位置现在都不可修改迭代。

这仅用于调试。找到问题并更正后,再次删除逻辑。

答案 1 :(得分:0)

检查ConcurrentModificationException和ArrayList

的文档

https://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html

https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html

要解决您的问题,请检查以下代码。

例如,

import java.util.*;

public class HelloWorld{

     public static void main(String []args){
        List<String> animals = new ArrayList<>();
        animals.add("Cat1");
        animals.add("Cat2");
        animals.add("Cat3");
        animals.add("Cat4");
        animals.add("Cat5");

        for(ListIterator<String> iterator = animals.listIterator(); iterator.hasNext();) {
            String name = iterator.next();
            if (name.equals("Cat2")) {
                iterator.remove();
                continue;
            }
            System.out.println(name);
        }
     }
}

干杯!!!