在Java中使用增强for循环结合迭代器?

5

好的,我的课程项目涉及到一个 "Sprite" 类的 ArrayList,我使用增强型 for 循环遍历它,有时需要删除当前正在查看的 Sprite。我被告知可以使用迭代器来安全地进行此操作(即不会删除当前正在查看的 Sprite)。我在 Oracle 的 Java 文档中查阅了相关内容,但并没有真正理解。

以下是我的方法:

public void forward() {
    for (Sprite s : sprites) {
        s.move();
        for(Sprite x : sprites){
            if(s!=x && s.overlaps(x)){                  
                if(s instanceof Razorback && x instanceof Opponent){
                    x.hit();
                }
                if(x instanceof Razorback && s instanceof Opponent){
                    s.hit();
                }
            }

        }
        if(s.shouldRemove())
            sprites.remove(s);

    }

}

如果(s.shouldRemove())为真,我需要实现一个迭代器。如果 shouldRemove() 返回 true,则需要从 ArrayList 中删除 s。


1
很确定你不能这样做,因为你需要调用“迭代器”的“remove”方法。 - MadProgrammer
你需要使用旧的for循环来安全地移除项目。外部for循环必须从最大长度开始,例如for(int i = sprites.size(); i >= 0; i--)。否则,可能会导致“ConcurrentModificationException”异常。内部循环保持不变。 - Juneyoung Oh
2个回答

10
你需要使用迭代器本身来循环(和删除)。
for (Sprite s : sprites) {

应该被更改为,

Iterator<Sprite> it = sprites.iterator();
while (it.hasNext()) {
    Sprite s = it.next();

那么你的if条件将会是这样的:

if (s.shouldRemove())
    it.remove();

你应该使用一个 Iterator<Sprite> - Paul Boddington
好的,谢谢!看起来完美运行了,但是 s 是如何递增的呢?我看到 s=it.next,但 it.next 不是每次都一样吗?还是 it.hasNext 自动递增它或者其他什么? - user3304654
@user3304654:next方法既将光标移动到下一个元素,又返回该元素。我本来想让你去查看文档,但我发现它实际上并不是100%清晰的! - Lii

9

除了@Codebender的回答之外:为了限制迭代变量的范围,您可以使用普通的for循环:

for(Iterator<Sprite> it = sprites.iterator(); it.hasNext(); ) {
    Sprite s = it.next();

    ...
    if (s.shouldRemove())
        it.remove();
}

这种写法导致循环结束后it变量未被定义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接