Java Reference
In-Depth Information
The most recent solution, using an
Iterator
, is available for all collections in the Java class
library and thus is an important code pattern that we shall use again in later projects.
4.12.2 Removingelements
Another important consideration when choosing which looping structure to use comes in when
we have to remove elements from the collection while iterating. An example might be that we
want to remove all tracks from our collection that are by an artist we are no longer interested in.
We can quite easily write this in pseudo-code:
for each track in the collection {
if track.getArtist() is the out-of-favor artist:
collection.remove(track)
}
It turns out that this perfectly reasonable operation is not possible to achieve with a
for-each loop. If we try to modify the collection using one of the collection's
remove
methods while in the middle of an iteration, the system will report an error (called a
ConcurrentModificationException
). This happens because changing the collection in
the middle of an iteration has the potential to thoroughly confuse the situation. What if the re-
moved element was the one we were currently working on? If it has now been removed, how
should we find the next element? There are no generally good answers to these potential prob-
lems, so using the collection's
remove
method is just not allowed during an iteration with the
for-each loop.
The proper solution to removing while iterating is to use an
Iterator
. Its third method (in
addition to
hasNext
and
next
) is
remove
. It takes no parameter and has a
void
return type.
Calling
remove
will remove the item that was returned by the most recent call to
next
. Here is
some sample code:
Iterator<Track> it = tracks.iterator();
while(it.hasNext()) {
Track t = it.next();
String artist = t.getArtist();
if(artist.equals(artistToRemove)) {
it.remove();
}
}
Once again, note that we do not use the
tracks
collection variable in the body of the loop.
While both
ArrayList
and
Iterator
have
remove
methods, we must use the
Iterator
's
remove
method, not the
ArrayList
's.
Using the
Iterator
's
remove
is less flexible: we cannot remove arbitrary elements, but only
the last element we retrieved from the
Iterator
's
next
method. On the other hand, using the
Iterator
's
remove
is allowed during an iteration. Because the
Iterator
itself is informed
of the removal (and does it for us), it can keep the iteration properly in sync with the collection.
Such removal is not possible with the for-each loop, because we do not have an
Iterator
there to work with. In this case, we need to use the while loop with an
Iterator
.
Search WWH ::
Custom Search