Leepoint Java Reference Notes on the Java language and its standard library.

The for-each loop

Use it whenever you can, which is most of the time.

The enhanced for loop — everyone calls it for-each — visits every element of an array or collection without you managing an index.

for (String name : names) {
    System.out.println(name);
}

Read the colon as “in”. It works on any array and on anything implementing Iterable, which includes every standard collection.

Why prefer it

The indexed equivalent has three places to make a mistake:

for (int i = 0; i <= names.length; i++) {   // off-by-one, throws
    System.out.println(names[i]);
}

Wrong bound, wrong start, wrong increment — all common, none possible with for-each. If you do not need the index, not having one removes a whole category of bug.

The two things it cannot do

You cannot modify the collection while iterating. Removing or adding during a for-each throws ConcurrentModificationException:

for (String s : list) {
    if (s.isEmpty()) list.remove(s);    // throws
}

Use removeIf, or an explicit iterator:

list.removeIf(String::isEmpty);

You cannot assign to the loop variable and affect anything. The variable is a copy of the reference:

for (String s : names) {
    s = s.trim();        // does nothing to names
}

For arrays of primitives the same applies — you are working on a copy of the value. If you need to write back, you need the index:

for (int i = 0; i < values.length; i++) {
    values[i] = values[i] * 2;
}

When you need the index anyway

If you need to know where you are — reporting a position, comparing to the previous element, or filling a parallel array — use the ordinary for loop. Do not fake it with a counter inside a for-each; that is the worst of both.

A note on order

For a List or an array, for-each visits elements in order. For a HashSet or HashMap there is no defined order and it can change between runs. If order matters, use a List, a LinkedHashSet or a TreeSet — do not rely on what a HashSet happens to do today.