Hero Background

Next-Gen App & Browser Testing Cloud

Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

Next-Gen App & Browser Testing Cloud

Java for-each Loop (Enhanced for Loop) With Examples

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.

What Is the for-each Loop in Java

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.

Syntax of the for-each Loop

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
}
  • Type — the type of a single element (e.g. int, String, or a custom class). It must be assignment-compatible with the element type of the source.
  • item — a fresh local variable that receives a copy of the current element on each iteration.
  • collection — an array or any object implementing Iterable (List, Set, Queue, and so on).

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()).

Iterating an Array

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 = 16

The 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);
}

Iterating Collections - List, Set, and Map

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);
}

for-each vs Traditional for Loop

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.

  • Index access: for-each (Enhanced) has no index available; Traditional for gives full index access.
  • Modify in place: for-each (Enhanced) cannot reassign elements; Traditional for can set arr[i] = value.
  • Readability: for-each (Enhanced) is concise and clear; Traditional for has more boilerplate.
  • Direction: for-each (Enhanced) is forward only; Traditional for is forward or backward.
  • Performance: for-each (Enhanced) and Traditional for are effectively identical.

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.

for-each Loop vs the forEach() Method

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);
  • Flow control — the for-each loop supports break, continue, and return; a forEach() lambda cannot use break or continue.
  • Checked exceptions — a plain for-each loop can throw checked exceptions directly; a lambda passed to forEach() cannot, without wrapping.
  • StreamsforEach() shines at the end of a Stream pipeline (filter/map), where the for-each statement does not apply.
  • Readability — prefer the for-each loop for simple side effects and control flow; prefer forEach() for concise, functional-style processing.

Limitations of the for-each Loop

The convenience comes with constraints. Knowing these up front keeps you from reaching for a for-each loop in situations it cannot handle:

  • No index. You cannot tell which position you are at, so you cannot print "element 3 of 5" or treat the first or last element specially without an external counter.
  • Read-only for structural changes. You cannot add or remove elements from the underlying collection during iteration — doing so throws a ConcurrentModificationException.
  • No parallel iteration. A single for-each loop walks one source. To step through two arrays or lists in lockstep, you need a traditional indexed loop driving both.
  • Cannot easily remove elements. Because there is no exposed iterator, you cannot call iterator.remove(); use an explicit Iterator or removeIf() instead.
  • Cannot iterate backwards. The for-each loop always moves forward from the first element to the last.

Common Mistakes and Troubleshooting

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.

  • ConcurrentModificationException — calling list.add() or list.remove() inside the loop corrupts the iterator. Remove safely with an explicit Iterator or collection.removeIf(predicate).
  • Reassigning the loop variable does nothing — setting item = newValue changes only the local copy, not the array or list element. Use an indexed loop and arr[i] = newValue to mutate in place.
  • NullPointerException on the source — a for-each over a null array or collection throws an NPE before the first iteration. Guard with a null check or initialize to an empty collection.
  • Autoboxing surprises — looping a List<Integer> into an int works via unboxing, but a null element will throw an NPE during unboxing. Loop into the wrapper type when nulls are possible.

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"));

Conclusion

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.

Frequently Asked Questions

What is the for-each loop 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.

Can you modify a collection inside a for-each loop?

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.

What is the difference between for-each and a traditional for loop?

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.

Can the for-each loop iterate over a Map in Java?

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.

Does the for-each loop work with arrays and collections both?

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.

What is the difference between forEach() and the for-each loop in Java?

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.

When should you not use a for-each loop in Java?

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().

Related Questions

Test Your Website on 3000+ Browsers

Get 100 minutes of automation test minutes FREE!!

Test Now...

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

  • Advanced access controls
  • Advanced data retention rules
  • Advanced Local Testing
  • Premium Support options
  • Early access to beta features
  • Private Slack Channel
  • Unlimited Manual Accessibility DevTools Tests