00:00

for-each Loop in Java – Enhanced for Loop with Examples

The for-each loop, officially the enhanced for loop, visits every element of an array or collection one by one, without an index or an iterator in sight. Introduced in Java 5, it is the simplest and safest way to read through data, and you will see it in almost every Java program.

This tutorial shows how to use for-each with arrays, lists, sets and maps, explains how it works behind the scenes, and covers its limitations and when to use a classic for loop instead.

1. Syntax

Syntax
for (Type element : arrayOrIterable) {
    // use element
}

Read the colon as "in": for each price in prices. The variable takes the value of each element in turn, from first to last.

2. Looping Over Arrays

ForEachArray.java
public class ForEachArray {
    public static void main(String[] args) {
        double[] prices = {120.0, 45.5, 300.0, 89.99};

        double total = 0;
        for (double price : prices) {          // read each element in order
            total += price;
        }
        System.out.printf("Total: %.2f, average: %.2f%n", total, total / prices.length);

        String[] fruits = {"mango", "apple", "kiwi"};
        for (String fruit : fruits) {
            System.out.println(fruit.toUpperCase());
        }
    }
}
Output
Total: 555.49, average: 138.87
MANGO
APPLE
KIWI

Compare this with the index-based version, for (int i = 0; i < prices.length; i++) total += prices[i];. The for-each loop removes the index, the bounds and the chance of an off-by-one error.

3. Looping Over Collections and Maps

Any List, Set, Queue or other Iterable works the same way. A Map is not iterable itself, so loop over one of its views: entrySet(), keySet() or values().

ForEachCollections.java
import java.util.*;

public class ForEachCollections {
    public static void main(String[] args) {
        List<String> tasks = List.of("design", "build", "test");
        for (String task : tasks) System.out.print(task + " ");
        System.out.println();

        Set<Integer> ids = new TreeSet<>(Set.of(42, 7, 19));
        for (int id : ids) System.out.print(id + " ");      // unboxing Integer -> int
        System.out.println();

        Map<String, Integer> stock = new LinkedHashMap<>();
        stock.put("pens", 120);
        stock.put("books", 35);
        for (Map.Entry<String, Integer> e : stock.entrySet()) {
            System.out.println(e.getKey() + " -> " + e.getValue());
        }

        // Iterable.forEach with a lambda (Java 8+)
        tasks.forEach(t -> System.out.print("[" + t + "] "));
        System.out.println();
    }
}
Output
design build test 
7 19 42 
pens -> 120
books -> 35
[design] [build] [test]

The last line uses Iterable.forEach() with a lambda, a method-based alternative added in Java 8.

4. How for-each Works Behind the Scenes

The compiler translates a for-each loop into ordinary code:

What the compiler generates (simplified)
// For an array: an index loop
for (int i = 0; i < prices.length; i++) {
    double price = prices[i];
    ...
}

// For an Iterable: an iterator loop
for (Iterator<String> it = tasks.iterator(); it.hasNext(); ) {
    String task = it.next();
    ...
}

That is why any class implementing Iterable can be used in a for-each loop, including your own:

CountdownRange.java
import java.util.Iterator;

// Any class that implements Iterable can be used in a for-each loop
public class CountdownRange implements Iterable<Integer> {
    private final int from;

    CountdownRange(int from) { this.from = from; }

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<>() {
            private int current = from;
            public boolean hasNext() { return current >= 1; }
            public Integer next() { return current--; }
        };
    }

    public static void main(String[] args) {
        for (int n : new CountdownRange(5)) {
            System.out.print(n + " ");
        }
        System.out.println("go!");
    }
}
Output
5 4 3 2 1 go!

5. Limitations of the for-each Loop

ForEachLimits.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.List;

public class ForEachLimits {
    public static void main(String[] args) {
        // 1. The loop variable is a copy: changing it does not change the array
        int[] scores = {10, 20, 30};
        for (int s : scores) {
            s = s * 2;
        }
        System.out.println("After for-each: " + Arrays.toString(scores));

        for (int i = 0; i < scores.length; i++) scores[i] *= 2;   // use an index to modify
        System.out.println("After indexed loop: " + Arrays.toString(scores));

        // 2. Removing elements inside for-each fails
        List<String> names = new ArrayList<>(List.of("Asha", "Ravi", "Anil", "Meera"));
        try {
            for (String n : names) {
                if (n.startsWith("A")) names.remove(n);
            }
        } catch (ConcurrentModificationException e) {
            System.out.println("ConcurrentModificationException while removing");
        }
        names.removeIf(n -> n.startsWith("A"));                   // the safe way
        System.out.println("After removeIf: " + names);

        // 3. Need an index? Keep a counter, or use a classic for loop
        int position = 1;
        for (String n : names) System.out.println(position++ + ". " + n);
    }
}
Output
After for-each: [10, 20, 30]
After indexed loop: [20, 40, 60]
ConcurrentModificationException while removing
After removeIf: [Ravi, Meera]
1. Ravi
2. Meera
  • No index: you cannot directly tell which position you are at. Keep a counter or use a classic for loop.
  • Read-only for arrays of primitives: the loop variable is a copy, so assigning to it does not change the array. (For objects, you can still call methods that change the object.)
  • No removal: removing elements from a collection inside for-each throws ConcurrentModificationException. Use removeIf() or an explicit iterator.
  • Forward only, all elements: no reverse order, no skipping by steps, no partial ranges (unless you loop over a sub-list or reversed() view).
  • One collection at a time: you cannot walk two arrays in parallel.
  • null source: looping over a null array or collection throws NullPointerException.

6. for-each vs Classic for Loop

NeedUse
Read every element in orderfor-each
Know the index or positionClassic for
Modify array elementsClassic for
Iterate backwards or in stepsClassic for (or reversed() in Java 21)
Remove while iteratingIterator or removeIf()
Transform, filter or aggregateStreams, e.g. list.stream().filter(...).toList()

7. Summary

  • for (Type x : source) visits every element of an array or Iterable.
  • It is shorter and safer than index loops and cannot go out of bounds.
  • The compiler turns it into an index loop for arrays and an iterator loop for collections.
  • It cannot give you the index, modify primitive arrays, or remove elements safely.
  • Use the classic for loop, an iterator or streams when you need those abilities.

Related Tutorials

Reference: Java Language Specification §14.14.2: The enhanced for statement