Next-Gen App & Browser Testing Cloud
Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

The Java for-each loop (also called the enhanced for loop) iterates over arrays and collections without an index, using the syntax for (Type item : collection) { ... }. On each pass it copies the next element into the loop variable, so you read every value in order without managing a counter or calling an iterator. This makes iteration cleaner, shorter, and far less error-prone than a classic indexed loop.
Introduced in Java 5, the for-each loop works on any array and on any object that implements the Iterable interface — including List, Set, and most other collections. Below we cover its syntax, runnable examples for arrays, Lists, Sets, and Maps, how it compares to the traditional for loop, and the limitations and mistakes every developer should know.
The for-each loop is a control-flow statement, added in Java 5 (J2SE 5.0), that traverses every element of an array or collection one at a time. Instead of declaring a counter, checking a bound, and incrementing it, you simply declare a variable of the same type as the elements, separate it from the source with a colon, and let the compiler walk the structure for you.
Under the hood, the for-each loop is syntactic sugar. For an array, the compiler expands it into an indexed loop; for a collection it expands into a call to the iterator() method and repeated hasNext() / next() calls. That is why it works on any type that implements java.lang.Iterable. The benefit is purely readability and safety — you cannot fall off the end of the array or accidentally skip an index.
The syntax has three parts: the element type, the loop variable, and the source array or collection, all inside the parentheses and separated by a colon. Read the colon as the word "in".
for (Type item : collection) {
// body runs once per element,
// with "item" holding the current element
}A useful trick is to declare the element type as var (Java 10+) so the compiler infers it, which keeps generic-heavy loops concise: for (var entry : map.entrySet()).
Arrays are the most common use case. Declare the loop variable with the array's base type, then read each element directly — no index arithmetic, no array.length bound to get wrong.
public class ArrayForEach {
public static void main(String[] args) {
int[] numbers = {1, 3, 5, 7};
// for-each loop over an int array
int sum = 0;
for (int num : numbers) {
System.out.println(num);
sum += num;
}
System.out.println("Sum = " + sum);
}
}
// Output:
// 1
// 3
// 5
// 7
// Sum = 16The same pattern works for object arrays. Here the loop variable is a String, and the body simply prints each value in declaration order:
String[] languages = {"Java", "Kotlin", "Scala"};
for (String language : languages) {
System.out.println("JVM language: " + language);
}Because List and Set implement Iterable, the for-each loop handles them exactly like an array. A List preserves insertion order, while a Set iterates in its own order (a HashSet is unordered; a LinkedHashSet keeps insertion order).
import java.util.*;
public class CollectionForEach {
public static void main(String[] args) {
// Iterating a List
List<String> fruits = new ArrayList<>(List.of("Apple", "Banana", "Cherry"));
for (String fruit : fruits) {
System.out.println("Fruit: " + fruit);
}
// Iterating a Set
Set<Integer> ids = new LinkedHashSet<>(List.of(101, 102, 103));
for (int id : ids) {
System.out.println("ID: " + id);
}
}
}A Map is not directly Iterable, so you cannot put a raw map after the colon. Instead, loop over one of its three views: entrySet() for key-value pairs, keySet() for keys, or values() for values. Using entrySet() is the most efficient way to read both the key and the value together.
import java.util.*;
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 90);
scores.put("Bob", 85);
// Iterate keys and values together via entrySet()
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
System.out.println(entry.getKey() + " => " + entry.getValue());
}
// Iterate only the keys
for (String name : scores.keySet()) {
System.out.println("Name: " + name);
}Neither loop is universally better — they solve different problems. The for-each loop wins on readability and safety; the traditional for loop wins when you need control over the index. The list below summarizes the trade-offs. If you want a refresher on the classic counter-based loop, see our guide on the Java for loop, and for condition-driven iteration the Java while loop.
On performance, the two are practically the same. For arrays the for-each loop compiles down to an indexed loop, and for collections it compiles down to the same iterator the traditional loop would use. Choose based on whether you need the index, not on speed.
People often conflate two different things: the for-each loop (a language statement, for (Type item : collection)) and the forEach() method (an API method added in Java 8 on Iterable and Stream that takes a lambda). Both visit every element, but they are not interchangeable in style or capability.
List<String> fruits = List.of("Apple", "Banana", "Cherry");
// 1) for-each loop (statement) — supports break, continue, and return
for (String fruit : fruits) {
System.out.println(fruit);
}
// 2) forEach() method (Java 8+) — takes a lambda/Consumer, great for streams
fruits.forEach(fruit -> System.out.println(fruit));
// 3) forEach() on a Stream with a pipeline
fruits.stream()
.filter(f -> f.startsWith("B"))
.forEach(System.out::println);The convenience comes with constraints. Knowing these up front keeps you from reaching for a for-each loop in situations it cannot handle:
Two mistakes account for most for-each bugs: modifying the collection mid-loop, and expecting changes to the loop variable to stick. Both come from misunderstanding that the loop variable is a copy of the element, not the element itself.
The example below shows the safe way to remove elements while iterating, using an explicit Iterator instead of a for-each loop:
import java.util.*;
List<String> names = new ArrayList<>(List.of("Ann", "Bob", "Cara"));
// WRONG: throws ConcurrentModificationException
// for (String name : names) { if (name.equals("Bob")) names.remove(name); }
// RIGHT: use an explicit Iterator
Iterator<String> it = names.iterator();
while (it.hasNext()) {
if (it.next().equals("Bob")) {
it.remove();
}
}
// Or, simplest of all:
names.removeIf(name -> name.equals("Bob"));The Java for-each loop gives you clean, readable, forward iteration over arrays and Iterable collections without the bookkeeping of an index. Use it whenever you only need each element's value, and fall back to a traditional for loop or an explicit Iterator when you need the index, in-place modification, parallel iteration, or safe element removal. Master those boundaries — plus the ConcurrentModificationException and copy-semantics gotchas — and the for-each loop becomes the default, safest way to traverse data in Java.
The for-each loop, also called the enhanced for loop, was introduced in Java 5 to iterate over arrays and Iterable collections without a manual index or iterator. It uses the syntax for (Type item : collection) and reads each element into the loop variable on every pass.
No. Adding or removing elements from a collection while iterating it with a for-each loop throws a ConcurrentModificationException. To remove elements safely, use an explicit Iterator and call iterator.remove(), or use the collection's removeIf() method instead.
A traditional for loop exposes an index, so it can access positions, count, modify elements, and iterate backwards. The for-each loop hides the index, giving cleaner, read-only forward iteration that is ideal when you only need each element's value.
Yes, indirectly. A Map is not directly Iterable, but you can loop over map.entrySet() to read both keys and values, or over map.keySet() or map.values() to read keys or values alone with a single for-each loop.
Yes. The for-each loop works on any Java array and on any object that implements the Iterable interface, which includes List, Set, Queue, and most other Collection types, so the same syntax covers both arrays and collections.
The for-each loop is a language statement that supports break, continue, and return. The forEach() method, added in Java 8 on Iterable and Stream, takes a lambda and is ideal for functional, stream-based processing, but it cannot use break or continue.
Avoid the for-each loop when you need the element index, must modify or remove elements during iteration, want to iterate backwards, or need to walk two collections in parallel. In those cases use a traditional indexed for loop or an explicit Iterator with removeIf().
KaneAI - Testing Assistant
World’s first AI-Native E2E testing agent.

TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance