【问题标题】:Every iteration of the game I want it to reduce the life time by 1游戏的每一次迭代我都希望它的生命周期减少 1
【发布时间】:2016-06-30 00:54:33
【问题描述】:

所以我有一个数组列表,用于存储有关宇宙的不同对象(行星、彗星、恒星等)。而不是这样做:

planet.decreaseLifeTime(1);
star.decreaseLifeTime(1);
comet.decreaseLifeTime(1);

游戏的每一次迭代我都希望它的生命周期减少 1。我试过这个,但它不起作用:

private ArrayList<SpaceObject> universeEntities;

public void reduceLifeTime() {
    for (SpaceObject entity: universeEntities) {
        entity.decreaseLifeTime(1);
        if(entity.getLifeTime() <= 0) {
            erase(entity);
            System.out.println("This entity has been erased");
        }

        System.out.println("life time: " + entity.getLifeTime());
    }
}

对象是这样添加的:

planet = new Planet(500, 500, -2, -2, 25, Color.BLUE, this);
universeEntities.add(planet);

【问题讨论】:

  • 你有什么问题?
  • erase(entity) 行是否改变了universeEntities 列表?
  • 用循环包围它
  • 显示你的完整代码,
  • 嗯,不是“完整代码”,而是minimal reproducible example

标签: java object arraylist


【解决方案1】:

如果erase(entity) 正在修改 UniverseEntities 列表,java 会发疯。

您可以将要删除的 SpaceObject 存储在单独的列表中,然后在 for 循环之后将其删除。

您可以在不使用迭代器的情况下遍历 UniverseEntities 例如一个数字索引

【讨论】:

  • 这是我开始编程时犯的一个错误,我仍然偶尔会忘记删除一个项目会扰乱迭代周期。但请详细说明他进行擦除的方式有什么问题,以及究竟是什么让 Java 对此“发疯”。
  • 根据 Java API 文档 [API 2014],如果在迭代过程中修改了底层集合,则迭代器的行为是未指定的。
  • 这在删除迭代器当前指向的条目时尤其重要。几乎每个可迭代对象的实现都会遇到这样的问题。
【解决方案2】:

根据您对reduceLifeTime 方法的实现,问题可能出在其中调用erase 方法(取决于它的实现方式)。

如果erase 方法只是试图通过调用ArrayList 的remove 方法从universeEntities 集合中删除一个项目,它只会破坏一个迭代器。

考虑重新实现您的方法以:

public void reduceLifeTime() {
    Iterator<SpaceObject> iterator = universeEntities.iterator();
    while (iterator.hasNext()) {
        SpaceObject object = iterator.next();
        object.decreaseLifeTime(1);

        if(object.getLifeTime() <= 0) {
            iterator.remove();
            System.out.println("This entity has been erased.");
        }

        System.out.println(String.format("Life time: %d", object.getLifeTime()));
    }
}

完整的工作示例:

public class Test {
    private ArrayList<SpaceObject> universeEntities = new ArrayList<SpaceObject>();

    public Test() {
        universeEntities.add(new Planet());
        universeEntities.add(new Planet());
    }

    public void reduceLifeTime() {
        Iterator<SpaceObject> iterator = universeEntities.iterator();
        while (iterator.hasNext()) {
            SpaceObject object = iterator.next();
            object.decreaseLifeTime(1);

            if(object.getLifeTime() <= 0) {
                iterator.remove();
                System.out.println("This entity has been erased.");
            }

            System.out.println(String.format("Life time: %d", object.getLifeTime()));
        }
    }

    public static void main(String[] args) {
        Test test = new Test();

        while(true) {
            test.reduceLifeTime();
            // Endless loop. Need a quit condition.
        }
    }

    public static class SpaceObject {
        protected int life = 0;

        public SpaceObject(int life) {
            this.life = life;
        }

        public void decreaseLifeTime(int value) {
            this.life -= value;
        }

        public int getLifeTime() {
            return life;
        }
    }

    public static class Planet extends SpaceObject {
        public Planet() {
            super(10);
        }
    }
}

如果您不想使用迭代器,您可以收集应该在某种集合中删除的项目,从reduceLifeTime 方法返回,然后使用removeAll 删除。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-28
    • 2017-07-08
    • 2011-07-30
    • 2011-12-02
    • 2020-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多