Reputation: 90
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
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
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