[Solved] Using ArrayList<> adding and removing objects

Ok, so I’m planning on using ArrayList<> to add a PlayerRocket every time a rocket is fired.

I know that I can add them by using the add(Object o) method of the ArrayList<>.

Now what my problem is, is that my PlayerRocket has a boolean which says whether the rocket is active or not, and when that equals false, i need to remove that specific rocket from the arraylist. When i read the documentation, it says that using the method remove(Object o) removes the first one of that object off the list, how can i remove specific ones.

OR

is there an alternative, maybe where i can create my own ArrayList<> type class because i will need to iterate through the list as well?

Any help much appreciated

I don’t understand the problem.
Why isn’t iterating through the list working?
Btw if your list contains only Rockets you can use Generics so you don’t need to do type casting.

is this what you want?:


ArrayList<PlayerRocket> playerRocketsArray = new ArrayList<>(PlayerRocket);

for(PlayerRocket pr: playerRocketsArray){
   if(wantToRemoveRocket){
      playerRocketsArray.remove(pr);
   }
}

although this can cause issues (bad to remove items from a list you are looping through)

so this may be better for you:


ArrayList<PlayerRocket> playerRocketsArray = new ArrayList<>(PlayerRocket);
for (Iterator i = playerRocketsArray.listIterator(); i.hasNext();) {
   PlayerRocket pr = (PlayerRocket) i.next(); 
   if (wantToRemoveRocket) i.remove();
}

Thanks for the help so far, I think I can get to answer from here, what I’m looking for is once the active boolean equals false, then the rocket needs to be removed from the list, but I’m sure I can simply do an if check in the loop, my only problem is, i’ll need it to iterate through this every time i call the repaint method will this slow down my game?
Because the rocket shouldnt be rendered if it isnt active, that way i want to remove it from the screen and list.

Turns out I can’t use ArrayList<>. it isnt included in the libraries that get delivered to the device im working for.

How can I go about creating a clone of this class?

It sounds like pretty standard bullet removal. My standard approact is as follows (not in code, just example)

on each render(re paint)

loop through bullets (as in previous post)
check if the bullet can be remove (I useally give bullets a ‘life time’ and when they hit zero (and have not hit anything) remove them).
if it needs removing, remove it (as shown in previous post).
repeat.

Unless there are thousands of bullets (rockets in this case) or they need a lot of logic ran against them or the game is running on an old/slow device, just do this in the render loop.

if it does effect your FPS, just create a thread for this.

If this is of use and you would like me to put it into code just say.

…ArrayList<> is bog standard java…

It was a lot of use! Thank you, gives me the theory to it.

Err… Yeah blame RIM. I’m working with the BlackBerry JDE 4.5.0 and when i try and import it, it wont let me, which means I can’t use it :frowning:
So now i need to try and create a clone of it, which I’m skeptical of, because I’m not sure what the <> part of the ArrayList means.

Very odd. I have not worked with the blackberry JDT so cannot really comment.

<> is the object type. You can ignore this and get away with some clever tricks (as mentioned by a previous user)

but it just means that if your Array (or ArrayList) if going to hold a bunch of strings, you are telling it in advance. Just tell it the class. in this case, your array holds many PlayerRocket(s) so ‘new ArrayList’

out of interest, can you do the following without it complaining:


java.util.ArrayList<String> test = new java.util.ArrayList<String>();

I wouldn’t use an arraylist in this case. Maybe you could have a look at LinkedList, it’s much faster in removing elements.
In addition you can’t remove an element out of the list while you are iterating that way.

pseudocode:


LinkedList<PlayerRocket> playerRockets;
ArrayList<PlayerRocket> toremove;

public void checkPlayerRockets(){

//add rockets to the remove list
for(PlayerRocket pr:playerRockets){
if(pr.shouldBeRemoved(){
toremove.add(pr)
}
}
//remove rockets
for(PlayerRocket pr:toremove){
playerRockets.remove(pr)
}
toremove.clear();

}

Nope it complains. I’ll try and create my own class.

@Phibedy, why can’t I just remove from the array list?

as i said erlier, removing from a list you are looping through will break it.

e.g.

at item 5 of 10.

item 5 gets removed. there are no longer 10 items, loop get confused and breaks.
That is why you should use the ‘hasNext()’ loop i mentioned before or LinkedList way.

I had a look, blackberry does not have arraylists like you said it has its own version(s), you can write your own arraylist but I think blackberry wants you to use something like their ‘Vector’ class. see here: http://stackoverflow.com/questions/1428891/blackberry-jde-arraylist/1429744#1429744

Looks like I have two options now.
I can either make my own one, or try and use this one : http://www.blackberry.com/developers/docs/4.3.0api/net/rim/device/api/collection/util/UnsortedReadableList.html

honestly, I think my best idea would be to create my own one. That way i have complete control over it.

I found a much better way :open_mouth:
Blackberry has an Arrays class, if i extend that or even just use it on its own then I’m sorted

When you try to add or remove objects in an enhanced for loop, it throws a ConcurrentModificationException.

iterate backwards starting from highest index, then i–
a for loop not for each which uses an iterator
now you can, on the fly remove elements without a problem

Why “remove” when you can “reuse”? Much easier and faster too.

Because you can’t remove an object out of the list while you are iterating: http://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html

You could also do it that way: http://stackoverflow.com/questions/13307471/concurrent-modification-exception-in-java
but I would prefere mine.

I wrote a really hacky solution for this, the reason is because when you get more complex iterations you cannot use an iterator and predict which elements to remove via it.

Like for example, the UI subsystem receives a mouse-press, the UI subsystem iterates through it’s list of buttons and execute the appropriate button’s handler. In the button’s handler you remove the button from the UI subsytem, thus throwing a concurrent modification exception.

You can create a shallow clone your set as you iterate (not very memory efficient), or you can use CopyOnWriteArrayList . I wrote a solution for this (I am not very familiar with the JDK so it may be a redundant implementation) but you can see it here. It essentially stores all mutations to the list and only applies them when data is required to be retrieved about the arraylist. I.e, inserting an element or removing an element doesn’t do anything immediately to the list. Creating an iterator into the list applies the mutations, getting an element from the list applies the mutations, getting the size of the list applies the mutations etc.

https://github.com/JeremyWildsmith/JevaEngineSrc/blob/master/JevaCore/src/jeva/util/StaticSet.java

I’ve created my own ArrayList class. With the JDK I’m now allowed to use type so it’s specific for my PlayerRocket:

package {...}data;

import {...}PlayerRocket;

public class ArrayList {
	
	// Constants
	private final int DEFAULT_CAPACITY = 16;
	
	// Store the objects into an array
	public PlayerRocket[] elements;
	
	// Integer
	private int size = 0;
	
	// Methods
	// Constructor
	public ArrayList()
	{
		// set the default capacity of the array
		elements = new PlayerRocket[DEFAULT_CAPACITY];
		
	}
	// Add the object to the array
	public void add(PlayerRocket e)
	{
		if(getSize() >= DEFAULT_CAPACITY)
		{
			// Do nothing can't have more than 16 on screen at once
		}
		else
		{
			// add the object at specific point
			elements[size++] = e;
		}
	}
	
	
	// Remove the object at a certain location
	 public void remove(int i) {
		 // Check to see if it will cause an error
	        if (i < 0 || i > elements.length) {
	            throw new ArrayIndexOutOfBoundsException();
	        } else {
	        	// now set it to null
	            elements[i] = null;
	            // create a temporary list of objects
	            PlayerRocket[] tmp = new PlayerRocket[--size];
	            int foo = 0;
	            // iterate through the elements list and add any non-null to tmp
	            for(int j = 0; j < elements.length; j++) {
	                if(elements[j] != null) {
	                    tmp[foo] = elements[j];
	                    foo++;
	                }
	            }
	            // make elements equal to the tmp
	            elements = tmp;
	        }
	    }

	
	// Getters and Setters
	public int getSize() {
		return size;
	}
	public void setSize(int size) {
		this.size = size;
	}
	
	public PlayerRocket[] getContents()
	{
		return elements;
	}
	
	public PlayerRocket getElement(int i)
	{
		return elements[i];
	}

}

And if i removed whilst iterating, i get an ArrayOutOdBoundsException.

Also I cannot use the LinkedList. It isnt available to me