在内部从ArrayList中删除元素

时间:2014-01-15 07:02:23

标签: java collections arraylist

我有以下代码:

class Action {

    public void step(Game game) {
        //if some condition met, 
        // then remove self from action stack
        game.actionStack.remove(this);

}


class Game (

    public ArrayList<Action> actionStack;

    public Game() {
        actionStack = new Arraylist<Action>();
        actionStack.add(new Action());

        while (true) {
            for (Action action : this.actionStack) {
                action.step(this);
            }
        }
    }
}

发生game.actionStack.remove(this);时会抛出异常。有没有办法从我想要的Action类中安全地删除元素?

4 个答案:

答案 0 :(得分:4)

我猜你得到了一个ConcurrentModificationException,因为你在迭代时调用了list remove方法。你不能这样做。

一个简单的解决方法是在迭代时处理数组的副本:

for (Action action : new ArrayList<>(this.actionStack)) {
    action.step(this);
}

稍微高效的修复方法是使用显式迭代器并调用其remove方法。或许step()返回一个布尔值,表示是否要保留在列表中以进行下一步:

for (Iterator<Action> it = this.actionStack.iterator(); it.hasNext();) {
    Action action = it.next();
    if (!action.step(this)) {
        it.remove();
    }
}

答案 1 :(得分:1)

来自:the java tutorial我们得到以下内容:

  

迭代器

     

...

     

请注意Iterator.remove是在迭代期间修改集合的唯一安全方法;如果在迭代进行过程中以任何其他方式修改基础集合,则行为未指定。

     

在需要时使用Iterator代替for-each构造:

     
      
  • 删除当前元素。 for-each构造隐藏了迭代器,因此您无法调用remove。因此,for-each构造不可用于过滤。
  •   
  • 并行迭代多个集合。
  •   
     

以下方法向您展示如何使用Iterator过滤任意Collection - 也就是说,遍历删除特定元素的集合。

static void filter(Collection<?> c) {
    for (Iterator<?> it = c.iterator(); it.hasNext(); )
        if (!cond(it.next()))
            it.remove();
}
  

这段简单的代码是多态的,这意味着无论实现如何,它都适用于任何Collection。此示例演示了使用Java Collections Framework编写多态算法是多么容易。

答案 2 :(得分:0)

注意:我认为,您为班级实施了equalshashCode方法 您需要使用迭代器来删除,如下所示;

class Game (

    public ArrayList<Action> actionStack;

    public Game() {
        actionStack = new Arraylist<Action>();
        actionStack.add(new Action());

        while (true) {
            for (Iterator<Action> it = this.actionStack.iterator(); it.hasNext(); ) {
               it.remove();
            }
        }
    }
}

编辑:步骤功能是做简单的删除工作。我将其移至Game构造函数

答案 3 :(得分:0)

我怀疑你得到了一个并发修改例外。我建议你这样做

class Action {

    public void step(Game game) {
        //if some condition met, 
        // then remove self from action stack
        List<Action> tmpActionList = new List<Action>();
        tmpActionList = game.actionStack
        tmpActionList.remove(this);
        game.actionStack = tmpActionList;
    }
}

让我知道它是否有效。