This question already has an answer here:
In Java, is it legal to call remove on a collection when iterating through the collection using a foreach loop? For instance:
List<String> names = ....
for (String name : names) {
// Do something
names.remove(name).
}
As an addendum, is it legal to remove items that have not been iterated over yet? For instance,
//Assume that the names list as duplicate entries
List<String> names = ....
for (String name : names) {
// Do something
while (names.remove(name));
}
I didn't know about iterators, however here's what I was doing until today to remove elements from a list inside a loop:
This is always working, and could be used in other languages or structs not supporting iterators.
Make sure this is not code smell. Is it possible to reverse the logic and be 'inclusive' rather than 'exclusive'?
The situation that led me to this page involved old code that looped through a List using indecies to remove elements from the List. I wanted to refactor it to use the foreach style.
It looped through an entire list of elements to verify which ones the user had permission to access, and removed the ones that didn't have permission from the list.
To reverse this and not use the remove:
When would "remove" be preferred? One consideration is if gien a large list or expensive "add", combined with only a few removed compared to the list size. It might be more efficient to only do a few removes rather than a great many adds. But in my case the situation did not merit such an optimization.
You clone the list
names
and iterate through the clone while you remove from the original list. A bit cleaner than the top answer.To safely remove from a collection while iterating over it you should use an Iterator.
For example:
From the Java Documentation :
Perhaps what is unclear to many novices is the fact that iterating over a list using the for/foreach constructs implicitly creates an iterator which is necessarily inaccessible. This info can be found here
Those saying that you can't safely remove an item from a collection except through the Iterator aren't quite correct, you can do it safely using one of the concurrent collections such as ConcurrentHashMap.