I have a sketch that creates a new object and adds it into an ArrayList every xxx number of seconds using a timer.
I would like each object created to have a life span, and then be deleted when it's life span finishes.
There are several ways of handling this problem. Two of them:
add a remainingTime variable to the class and update it each frame, as @Chrisir suggests. If the variable is <=0, remove.
add a removeTime variable to the class, which contains a millisecond clock time in the future when the object should be removed. Don't update any variables -- just check if they are < millis(). If so, remove.
Optimization: if your objects are added in order and will expire in order (e.g. same timer length), then you don't have to loop over your entire object list to check timers. You can just loop forward and check the first item -- if it isn't expired, nothing is, so break out. If it is expired, go on to the next entry. Once you hit the first non-expired item, loop backwards and delete expired items.
This doesn't matter much with small object counts and comparing ints, but would be helpful with very large object counts and/or more expensive checks (like distance calculations). Most frames you probably only need to check a single object -- not loop through 100 or 10000.
If you have a large number of objects and only a few of them will have timed removals (but most do not) then it might also make sense to register them in a separate list -- or if you can add timers onto an existing item then it might make sense to move them in the list when a timer is set.
If you have collections of items with synchronized timers, then you could have a list of timers, and attach objects to a timer. Then you remove a timer -- which removes all the objects attached to it, rather than iterating through e.g. 100 items that all expire at millis=25000.
In the end, the best model depends on assumptions about how many objects and how they are timed -- although assuming that there are many and that they are all independent gives you the most flexibility.
Wow, thanks for the feedback @jeremydouglass! You've got some interesting implementations there. I never thought of having synchronized timer groups. I'm starting to think this could be really useful.
@KevinWorkman I did quite a bit of searching. The function to remove an object from an ArrayList is pretty straight forward. I guess I should have been a little more specific with my question...
The part I can't figure out is how to get the correct index for the object I want to remove when its lifeSpan timer has ended. I know I can 'delete' the object with remove(index), but the lifeSpan timers will be random so the removal of the objects will be non-sequential.
@GoToLoop Indeed, the number of entries isn't fixed. I'm using .add() whenever a new object is created. I've never heard of a Queue. Going to do some research now!
The part I can't figure out is how to get the correct index for the object I want to remove when its lifeSpan timer has ended. I know I can 'delete' the object with remove(index), but the lifeSpan timers will be random so the removal of the objects will be non-sequential.
In that case you can just use a normal for loop to iterate over the ArrayList. Like other answers have said, looping backwards can avoid the problem of skipping over elements.
Ah, I see. I could make a function in the object that tests if the lifeSpan is finished, run for every instance, then remove if true. Thanks @KevinWorkman
Answers
Have you done any research? I'm surprised googling "remove object from arraylist" didn't return a ton of results.
Your first stop should be the reference.
https://Forum.Processing.org/two/discussions/tagged/backwards
show your entire code
in your class have lifeSpan variable and set it to 670 or a random number
every frame say lifeSpan--;
then for loop i backward over the ArrayList when list.get(i).lifeSpan <=0 list.remove (i);
There are several ways of handling this problem. Two of them:
add a remainingTime variable to the class and update it each frame, as @Chrisir suggests. If the variable is <=0, remove.
add a removeTime variable to the class, which contains a millisecond clock time in the future when the object should be removed. Don't update any variables -- just check if they are < millis(). If so, remove.
Optimization: if your objects are added in order and will expire in order (e.g. same timer length), then you don't have to loop over your entire object list to check timers. You can just loop forward and check the first item -- if it isn't expired, nothing is, so break out. If it is expired, go on to the next entry. Once you hit the first non-expired item, loop backwards and delete expired items.
This doesn't matter much with small object counts and comparing ints, but would be helpful with very large object counts and/or more expensive checks (like distance calculations). Most frames you probably only need to check a single object -- not loop through 100 or 10000.
If you have a large number of objects and only a few of them will have timed removals (but most do not) then it might also make sense to register them in a separate list -- or if you can add timers onto an existing item then it might make sense to move them in the list when a timer is set.
If you have collections of items with synchronized timers, then you could have a list of timers, and attach objects to a timer. Then you remove a timer -- which removes all the objects attached to it, rather than iterating through e.g. 100 items that all expire at millis=25000.
In the end, the best model depends on assumptions about how many objects and how they are timed -- although assuming that there are many and that they are all independent gives you the most flexibility.
If the # of objects is fixed, we can have an array plus a variable pointing to the current head index of it.
Items enter the array at current head index, which removes the oldest entry at the same time.
2 online examples which go w/ that optimized approach: :bz
However if the # of entries changes isn't fixed, we can use an Queue in place of a List for a better performance FIFO: *-:)
https://Forum.Processing.org/two/discussion/2829/fifo-queue-problem-with-code#Item_1
Wow, thanks for the feedback @jeremydouglass! You've got some interesting implementations there. I never thought of having synchronized timer groups. I'm starting to think this could be really useful.
@KevinWorkman I did quite a bit of searching. The function to remove an object from an ArrayList is pretty straight forward. I guess I should have been a little more specific with my question...
The part I can't figure out is how to get the correct index for the object I want to remove when its lifeSpan timer has ended. I know I can 'delete' the object with remove(index), but the lifeSpan timers will be random so the removal of the objects will be non-sequential.
@GoToLoop Indeed, the number of entries isn't fixed. I'm using .add() whenever a new object is created. I've never heard of a Queue. Going to do some research now!
In that case you can just use a normal
for
loop to iterate over theArrayList
. Like other answers have said, looping backwards can avoid the problem of skipping over elements.You could also use an Iterator.
Ah, I see. I could make a function in the object that tests if the lifeSpan is finished, run for every instance, then remove if true. Thanks @KevinWorkman
You need to do this in draw () not in the class and you need to do it in a backward for loop and then if
as I wrote above