Use an Iterator instead and use Iterator#remove method:
for (Iterator<String> it = a.iterator(); it.hasNext(); ) {
String str = it.next();
if (!str.equals("foo") || !str.equals("bar")) {
it.remove();
}
}
From your question:
messing with for iterators is not really good practice
In fact, if you code oriented to interfaces and use List instead of ArrayList directly, using get method could become into navigating through all the collection to get the desired element (for example, if you have a List backed by a single linked list). So, the best practice here would be using iterators instead of using get.
what is the best practice to remove items from a list efficiently?
Not only for Lists, but for any Collection that supports Iterable, and assuming you don't have an index or some sort of key (like in a Map) to directly access to an element, the best way to remove an element would be using Iterator#remove.
Java how to remove element from List efficiently - Stack Overflow
List.remove()
How does an ArrayList remove an element from an array?
java - Removing items from a list - Stack Overflow
Use an Iterator instead and use Iterator#remove method:
for (Iterator<String> it = a.iterator(); it.hasNext(); ) {
String str = it.next();
if (!str.equals("foo") || !str.equals("bar")) {
it.remove();
}
}
From your question:
messing with for iterators is not really good practice
In fact, if you code oriented to interfaces and use List instead of ArrayList directly, using get method could become into navigating through all the collection to get the desired element (for example, if you have a List backed by a single linked list). So, the best practice here would be using iterators instead of using get.
what is the best practice to remove items from a list efficiently?
Not only for Lists, but for any Collection that supports Iterable, and assuming you don't have an index or some sort of key (like in a Map) to directly access to an element, the best way to remove an element would be using Iterator#remove.
You have three main choices:
Use an
Iterator, since it has that handyremovemethod on it. :-)Iterator<String> it = list.iterator(); while (it.hasNext()) { if (/*...you want to remove `it.next()`...*/) { it.remove(); } }Loop backward through the list, so that if you remove something, it doesn't matter for the next iteration. This also has the advantage of only calling
list.size()once.for (int index = list.size() - 1; index >= 0; --index) { // ...check and optionally remove here... }Use a
whileloop instead, and only increment the index variable if you don't remove the item.int index = 0; while (index < list.size()) { if (/*...you want to remove the item...*/) { list.removeAt(index); } else { // Not removing, move to the next ++index; } }
Remember that unless you know you're dealing with an ArrayList, the cost of List#get(int) may be high (it may be a traversal). But if you know you're dealing with ArrayList (or similar), then...
I recently discovered that Java List (linked and array lists) in remove() method doesn't necessarily remove the exact given object (doesn't compare references using "==") but removes the first found object that is the same as the given one (compare using equals()). Can you somehow force it to remove the exact given object? It is problematic for handling a list possibly containing multiple different objects that have the same internal values.
Is it as simple as creating another array and moving all of the elements except the one to be deleted over?