Lars Kecker
Lars Kecker

Reputation: 90

Iterating two ArrayLists like in a 2-dimensional Array

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

Upvotes: 0

Views: 74

Answers (2)

vagelis
vagelis

Reputation: 334

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

Upvotes: 1

Julien Lopez
Julien Lopez

Reputation: 1844

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

Upvotes: 2

Related Questions