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
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
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());
}
}
}
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().
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();
}
}
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:
// 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:
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!");
}
}
5 4 3 2 1 go!
5. Limitations of the for-each Loop
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);
}
}
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
forloop. - 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. UseremoveIf()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.
nullsource: looping over anullarray or collection throwsNullPointerException.
6. for-each vs Classic for Loop
| Need | Use |
|---|---|
| Read every element in order | for-each |
| Know the index or position | Classic for |
| Modify array elements | Classic for |
| Iterate backwards or in steps | Classic for (or reversed() in Java 21) |
| Remove while iterating | Iterator or removeIf() |
| Transform, filter or aggregate | Streams, e.g. list.stream().filter(...).toList() |
7. Summary
for (Type x : source)visits every element of an array orIterable.- 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
forloop, an iterator or streams when you need those abilities.
Related Tutorials
Reference: Java Language Specification §14.14.2: The enhanced for statement
Frequently Asked Questions (FAQ)
Q1. What is a for-each loop in Java?
A loop that goes through every element of an array or Iterable collection without using an index: for (String name : names) { ... }. It is also called the enhanced for loop.
Q2. When was the for-each loop introduced?
In Java 5 (JDK 1.5), together with generics, autoboxing and enums.
Q3. Can I get the index in a for-each loop?
Not directly. Keep your own counter variable, or use a classic for loop when the index matters.
Q4. Can I modify array elements in a for-each loop?
Not for primitive arrays: the loop variable is a copy. Use an index loop to change elements. For arrays of objects, you can call methods that change each object, but you cannot replace the objects themselves.
Q5. Why do I get ConcurrentModificationException in a for-each loop?
Because the collection was changed structurally (an element added or removed) while its iterator was in use. Use removeIf(), an explicit Iterator with it.remove(), or collect changes and apply them after the loop.
Q6. Can I use for-each on a Map?
Not on the map itself, but on its views: for (Map.Entry<K, V> e : map.entrySet()), map.keySet() or map.values().
Q7. Can I iterate backwards with for-each?
Not directly. Use a classic for loop counting down, Collections.reverse() on a copy, or, in Java 21+, the reversed() view of a list or sequenced collection.
Q8. Which classes can be used with for-each?
All arrays and any class that implements java.lang.Iterable, which includes every Collection such as lists, sets and queues.
Q9. How do I make my own class work with for-each?
Implement Iterable<T> and return an Iterator<T> from its iterator() method, as the CountdownRange example does.
Q10. Is for-each faster than a classic for loop?
For arrays and ArrayList, performance is essentially the same. For a LinkedList, for-each is much faster than calling get(i) in an index loop.
Q11. What is the difference between for-each and forEach()?
for-each is a language statement. forEach() is a method on Iterable and streams that takes a lambda. The method cannot use break or continue, and lambdas can only use effectively final local variables.
Q12. Can I use break and continue in a for-each loop?
Yes. break stops the loop and continue moves to the next element, exactly as in other loops.
Q13. What happens if the array or list is null?
The loop throws NullPointerException. Check for null first, or better, use empty collections instead of null.
Q14. Can I loop over two arrays at once with for-each?
No. Use a classic for loop with one index for both arrays, after checking they have the same length.
Q15. Can I use var in a for-each loop?
Yes, since Java 10: for (var entry : map.entrySet()) lets the compiler infer the element type.
Q16. Does for-each work with primitive and wrapper types?
Yes. You can loop over an int[] with int, and over a List<Integer> with either Integer or int (auto-unboxing). Unboxing a null element throws NullPointerException.
Q17. Can I declare the loop variable final?
Yes: for (final String name : names). This makes it clear that the variable is not reassigned inside the loop.
Q18. Is the order of a for-each loop guaranteed?
For arrays and lists, yes: from the first to the last element. For sets and maps, the order depends on the implementation, for example insertion order for LinkedHashSet and no guaranteed order for HashSet.
Q19. Can for-each iterate over a String?
Not directly, because String is not Iterable. Use for (char c : text.toCharArray()), or text.chars() with streams.
Q20. When should I prefer streams over for-each?
When you transform, filter, group or aggregate data and want the result as a new collection or value. For simple actions with side effects, a for-each loop is usually clearer.