Question

Short introduction: I'm building a game, where monsters spawn at the top, and moves through a path, to the reach a point where they need to be removed/destroyed/deleted. But I can't seem to get the Monster Object deleted.

for (Monster i : Monstre) 
    {
        this.add(i); //adds monster to JPanel

if(i.monstery > 50 && i.monsterx > 50){  //check if monster have reached end point

        this.remove(i); //Should remove Object from the JPanel ?
        i = null; //Sets object too null
        Monstre.remove(i); //Removes object from arrayList "Monstre".

}else{
//Update the monsters bounds

The above removes the object from the JPanel, and it seems to be all good. But when i call System.out.println(Monstre.size()); I get an increasing amount of monsters spawned, and if increasing the monster spawn rate, the program starts to eventually slow down, because amount of monsters in the Monstre arraylist is over 9000, and never decreasing. What I'm looking for, is a way to remove these objects while the game is running.

Was it helpful?

Solution

Remove the i = null; line. This is not C and you don't have to assign your variables to null. JVM will do that for you (google "java garbage collection"). Because of that line, you practically call Monstre.remove(null) which does not work.

Also, you cannot iterate over the collection in that manner and modify it (remove values). Save the monsters you want to delete in an array outside of the scope of the loop, and remove them after the loop finishes. Otherwise, use an iterator:

Iterator<Monster> it= Monstre.iterator(); 
while (it.hasNext()) {
    Monster i= it.next();
    //code code code
    if (shouldDelete) {
        this.remove(i);
        it.remove();
    }
}

OTHER TIPS

In addition to the suggestion in the first answer, you should change your loop. Removing items from the Monstre list while using the for-each loop will cause problems.

Instead try :

 Iterator<Monster> iter = Monstre.iterator ();
 while (iter.hasNext()) 
    {
        i = iter.next();
        this.add(i); //adds monster to JPanel

        if(i.monstery > 50 && i.monsterx > 50){  //check if monster have reached end point

            this.remove(i);
            iter.remove();

        }else{

EDIT :

Here's an explanation where you can't use the for-each loop :

So when should you use the for-each loop? Any time you can. It really beautifies your code. Unfortunately, you cannot use it everywhere. Consider, for example, the expurgate method. The program needs access to the iterator in order to remove the current element. The for-each loop hides the iterator, so you cannot call remove. Therefore, the for-each loop is not usable for filtering. Similarly it is not usable for loops where you need to replace elements in a list or array as you traverse it. Finally, it is not usable for loops that must iterate over multiple collections in parallel. These shortcomings were known by the designers, who made a conscious decision to go with a clean, simple construct that would cover the great majority of cases.

    i = null; //Sets object too null
    Monstre.remove(i); //Removes object from arrayList "Monstre".

Here you set the variable i to null then you request that i (i.e. null) is removed from your arraylist, the arraylist does not contain null so nothing happens. Setting things equal to null is very rarely nessissary.

As you have correctly said removing the i=null upsets the program, this is because you are iterating through the list and then changing the list while iterating, you have two options;

1) go through the Arraylist in a manor similar to an array

import java.util.*;

public class Test{

    public static void main(String [] args){
        ArrayList<Double> doubles=new  ArrayList<Double>();

        for(double i=0;i<10;i++){
            doubles.add(i);
        }

        //remove 7.0s from doubles

        for(int i=doubles.size()-1;i>=0;i--){
            //must go through backwards - see http://stackoverflow.com/questions/12111210/java-arraylist-search-and-remove for why

            if (doubles.get(i).equals(7.0)){
                doubles.remove(i);
            }
        }

    }
}

2) use an iterator and its remove method

import java.util.*;

public class Test{

    public static void main(String [] args){
        ArrayList<Double> doubles=new  ArrayList<Double>();

        for(double i=0;i<10;i++){
            doubles.add(i);
        }

        //remove 7.0s from doubles

        Iterator<Double> iterator=doubles.iterator();

        while(iterator.hasNext()){
            Double testDouble=iterator.next();
            if (testDouble.equals(7.0)){
                iterator.remove();
            }
        }

    }
}

You cannot remove this element in a for-loop.

You need to use listIterator() method to retrieve an iterator that can be modified and loop with iterator-style. Otherwise you would always get java.util.ConcurrentModificationException

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top