7.7 Removing List Items in a for/in Loop
Another common task in loop
iteration, particularly over collections, is inloop
modification. This is all done through the iterator, as directly modifying
the collection creates all sorts of nasty loop problems. Instead,
using methods such as remove( ) from java.util.Iterator allows modifications
in a loop-safe way. However, since the iterator is hidden in for/in, this is another limitation of for/in.
7.7.1 How do I do that?
This is another one of those "You can't" recipes. To see exactly what it is
you can't do, take a look at the following code:
In particular, notice the second for loop, which uses remove( ) to yank
public void removeListItems(PrintStream out, String[] args)
throws IOException {
List<String> wordList = new LinkedList<String>( );
// Assign some words
for (int i=0; i<args.length; i++) {
wordList.add("word " + (i+1) + ": '" + args[i] + "'");
}
// Remove all words with "1" in them. Impossible with for/in
for (Iterator i = wordList.iterator( ); i.hasNext( ); ) {
String word = (String)i.next( );
if (word.indexOf("1") != -1) {
i.remove( );
}
}
// You can print the words using for/in
for (String word : wordList) {
out.println(word);
}
}
any words in the List with "1" in the text. This depends on the usage of
Iterator, which isn't available in for/in, so you're out of luck here.
7.7.2 What about...
...anything else that involves knowing where you are in the list? Nope
it's not possible. Here are just a few examples of other things you can't
do with for/in:
- Iterate backward through the elements of an array or List.Use a single loop counter to access similarly numbered or positioned
elements in two distinct arrays or collections.Iterate through the elements of a List using calls to get( ) rather
than calls to its iterator.
Watch out for this last oneit is a legitimate performance concern. For
the java.util.ArrayList class, for example, looping with the size( )
and get( ) methods is measurably faster than using the list's Iterator. In
many cases, the performance difference is negligible and irrelevant. But,
when writing an inner loop or other performance-critical code, you might
prefer to use a for loop with the get( ) method instead of a for/in loop.