0

I am trying to Iterate two ArrayList: One of them, called "gegner" is a list about enemys and another one called "waende" is about walls.

Whenever a wall and an Enemy touch, both should loose one durability / health. As it didn't work at the same time, I created a new method that should remove the death Objects from the Lists.

My idea was:

public void removeDeathObjects() {
    Wand tempW;
    Gegner tempG;
    for (Iterator<Gegner> it = gegner.iterator(); it.hasNext();) {
        tempG = it.next();
        for (Iterator<Wand> it2 = waende.iterator(); it2.hasNext();) {
            tempW = it2.next();

                if(tempW.isDestroyed()){
                    it2.remove();
                }
                if (tempG.isDeath()){
                    it.remove();
                }
        }   

    }
}

But the program throws an "Exception in thread "AWT-EventQueue-0" in the Line it.remove() java.lang.IllegalStateException" as soon as there are at least two walls, and the enimies aren't killed completely.

Where did I failed?

If you wanted, I could give you the whole code but it's pretty long ._.

PS: sorry for bad English

1
  • I don't get why your two loops are nested. Don't you just want something like gegner.removeIf(g -> g.isDeath())? Commented Apr 15, 2016 at 13:02

2 Answers 2

2

Your answer is here: http://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html#remove--

IllegalStateException - if the next method has not yet been called, or the remove method has already been called after the last call to the next method

Instead of iterating manually, you can do this in Java 8:

public void removeDeathObjects() {
    gegner.removeIf(g -> g.isDeath());
    waende.removeIf(w -> w.isDestroyed());
}
Sign up to request clarification or add additional context in comments.

Comments

1

Your mistake is that you have nested two completely independent loops. Looking at your code, it is evident that the inner loop on waende has nothing to do with the outer loop on gegner: your actions on waende do not depend on any check on gegner. What happens is that when tempG.isDeath() is true, it.remove() executes repeatedly, for every Wand in waende. The first removal on the iterator succeeds, but the second fails.

What you need to do is to separate the two loops:

public void removeDeathObjects() {
    Wand tempW;
    Gegner tempG;
    for (Iterator<Gegner> it = gegner.iterator(); it.hasNext();) {
        tempG = it.next();
        if (tempG.isDeath()){
            it.remove();
        }
    }
    for (Iterator<Wand> it2 = waende.iterator(); it2.hasNext();) {
        tempW = it2.next();
        if(tempW.isDestroyed()){
            it2.remove();
        }
    }   
}

2 Comments

You've swapped the two if blocks. ;-) Fix this and you have my up-vote. And might as well put tempG = it.next() and tempW = it2.next() directly in the for loop.
@JulienLopez Bah! Thanks for pointing out my mistake! As for the changes to the for loops, I like to touch questions' code as little as possible, if only to make clearer what I want to say.

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.