Java 5 for:each loops are the best. But you can't always for:each. Here's three idiomatic loop patterns that I like to use in my code...
Bytes in a stream
public void processBytes(InputStream in) throws IOException {
byte[] buffer = new byte[1024];
for (int count; (count = in.read(buffer)) != -1; ) {
process(buffer, 0, count);
}
}
This is better than the popular alternative that declares 'count' before the loop, and uses a while loop instead of a for loop. The for loop is better for two reasons:
- It saves a line of code!
- It decreases the visibility of count. If you have two of these loops in one method, you don't have to choose between count1/count2 or reusing a local variable.
Lines in a BufferedReader
public void processLines(BufferedReader in) throws IOException {
for (String line; (line = in.readLine()) != null; ) {
process(line);
}
}
As above, using a for loop instead of a while loop shortens the code and decreases the visibility of 'line'.
Indexed elements in an ArrayList
Sometimes for:each doesn't always work for collections. It lacks the current index, and it allocates an iterator which creates extra work for the garbage collector. So we iterate index-by-index:
public <T> void processElements(List<T> list) {
for (int i = 0, size = list.size(); i < size; i++) {
process(i, list.get(i));
}
}
Unlike the conventional loop, this calls size() once rather than N+1 times.