7

Okay so in my project for class I'm looking through an ArrayList of my class "Sprite" with an enhanced for loop, and I occasionally need to delete the Sprite that I'm looking at. I'm told I can do this safely (i.e. not deleting the Sprite I'm currently looking at) with Iterators. I looked it up on Oracle's java documentation but I don't really understand it..

Here's my method:

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);

    }

}

if(s.shouldRemove()) is where I need to implement an iterator. If shouldRemove() return true, s needs to be removed from the ArrayList.

2
  • 1
    Pretty sure you can't, as you need to call the Iterators remove method Commented Oct 8, 2015 at 5:28
  • You need to older for loop for removing item safely. Outter for loop must start from maximum length like for(int i = sprites.size(); i >= 0; i--). Otherwise, it could be a cause of ConcurrentModificationException. Inner loop is fine as is. Commented Oct 8, 2015 at 5:47

2 Answers 2

16

In addition to @Codebender answer: to limit the scope of the iterator variable, you can use plain for loop:

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

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

This way the it variable is undefined after the loop.

Sign up to request clarification or add additional context in comments.

1 Comment

Why is this code failing?? for(Iterator it=values().iterator(); it.hasNext(); it.next())
11

You need to loop (and remove) using the iterator itself.

for (Sprite s : sprites) {

should be changed to,

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

And then your if condition will be,

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

3 Comments

Okay thanks! Seems to be working perfectly, but how is s getting incremented? I see s=it.next, but isn't it.next the same every time? Or does it.hasNext automatically increment it or something?
@user3304654: next both moves the cursor to the next element and returns it. I was going to tell you to go look at the documentation but I discovered it actually isn't 100 % clear!
you can also use a predicate since java 1.8: sprites.removeIf(Sprite::shouldRemove)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.