Java Enhanced for Loop

In the last lesson you learned about the Java do-while loop. Every loop so far makes you manage a counter by hand, which is a lot of bookkeeping just to visit every item in a list.

So Java gives you a cleaner option made for exactly this: the enhanced for loop, also called the for-each loop.

🤔 Why do we need a for-each loop?

To print an array of names, a normal for loop makes you manage a counter by hand:

String[] names = {"Alex", "Riya", "Arjun"};
for (int i = 0; i < names.length; i++) {
System.out.println(names[i]);
}

That is a lot of parts to get right just to say “print every name”, and each is a place for a bug:

  • Start i at the right value, or you skip an item.
  • Wrong sign (<= instead of <) reads past the end.
  • A forgotten i++ makes the loop run forever.
  • A wrong index reaches the wrong slot.

None of this is about names. It is all just bookkeeping.

Like reading a guest list, you only care about the name, not that “Riya” is guest number two. The for-each loop hands you each item and skips all the counting.

🧩 The enhanced for loop syntax

The for-each loop reads almost like a sentence:

for (Type item : collection) {
// use item here, one element at a time
}

Read the : as “in”, so the line says “for each item in collection”:

  • No index, no condition, no update step. Java does that for you.
  • Each pass puts the next element into item. You use item directly.
  • The one rule: the type before the variable must match the elements. Use String for an array of strings, int for an array of ints.

💡 A simple example

The same array of names, now with a for-each loop:

String[] names = {"Alex", "Riya", "Arjun"};
for (String name : names) {
System.out.println(name);
}

“For each name in names, print the name”:

  • The loop variable name holds "Alex", then "Riya", then "Arjun".
  • The array is then finished, so the loop stops on its own.
  • No i, no names.length, no i++.

Output

Alex
Riya
Arjun

The loop knows the collection’s length already, so it ends exactly when there are no more items. One less thing to get wrong.

🖥️ A more real example

The for-each loop shines when you process values. Here we add up student marks to find the total.

public class TotalMarks {
public static void main(String[] args) {
int[] marks = {85, 90, 78, 92, 88};
int total = 0;
for (int mark : marks) {
total = total + mark;
}
System.out.println("Total marks: " + total);
}
}

Step by step:

  • total starts at 0, our running sum.
  • For each mark, we add it to total.
  • When the loop ends, total holds the sum of every mark.

We never touched an index. We only cared about the values. That is the sweet spot for for-each: visit every item and do something with each value.

Output

Total marks: 433

📋 It works on more than arrays

The for-each loop works on any Iterable, Java’s word for “something you can step through one item at a time”:

  • Arrays, but also a List, a Set, and many other collections.
  • The same clean syntax carries over to all of them.

Here we build a small List of cities, then print each one:

import java.util.List;
public class Cities {
public static void main(String[] args) {
List<String> cities = List.of("London", "Tokyo", "Cairo");
for (String city : cities) {
System.out.println(city);
}
}
}

The loop body did not change. Array or list, “for each city in cities” reads and works the same.

Output

London
Tokyo
Cairo

A Set works too. It holds items with no duplicates and no promised order, so a counter-based loop would be awkward there.

The for-each loop does not care about order, it just asks for each item in turn:

import java.util.Set;
public class UniqueTags {
public static void main(String[] args) {
Set<String> tags = Set.of("java", "loops", "basics");
for (String tag : tags) {
System.out.println(tag);
}
}
}

Set order is not fixed

A Set does not promise any particular order. So the three tags may print in a different order than you typed them. That is normal for a plain Set. The for-each loop still visits each item exactly once.

🚫 The limits of for-each

The for-each loop is clean because it hides things, but hiding means you give up control. So there are jobs it cannot do. These limits tell you when to reach for a normal for instead:

  • You cannot get the index. There is no i, so you never know “this is item number 3”. If you need the position, for-each cannot give it to you.
  • You cannot change a primitive element through the loop variable. For int, double, char and the like, the loop variable is a copy of the value. Editing the copy does nothing to the array.
  • You cannot safely remove items while looping a collection. Removing from a list or set inside a for-each throws a ConcurrentModificationException.
  • You cannot easily walk two arrays together. With a shared index i you can read a[i] and b[i] side by side. A for-each gives only one stream of values.
  • You cannot go backwards. A for-each always runs front to back. To go last-to-first you need a counter you control.

The copy point surprises people, so let’s make it concrete. Here we try to double every number by setting each n to n * 2, then print the array:

int[] numbers = {1, 2, 3};
for (int n : numbers) {
n = n * 2; // ❌ changes the copy, not the array
}
System.out.println(numbers[0] + " " + numbers[1] + " " + numbers[2]);

You might expect 2 4 6, but you get the original values back:

Output

1 2 3

Why? n is a fresh copy of each element. Changing it changes the copy, which is thrown away on the next pass, so the array slot is never touched.

To really edit the array, loop by index and assign to numbers[i]:

int[] numbers = {1, 2, 3};
for (int i = 0; i < numbers.length; i++) {
numbers[i] = numbers[i] * 2; // ✅ writes back into the array
}
System.out.println(numbers[0] + " " + numbers[1] + " " + numbers[2]);

Output

2 4 6

The removal limit matters too:

  • Call remove inside a for-each and Java notices the collection changed, then crashes with a ConcurrentModificationException.
  • To remove while looping, use an Iterator and its remove method, or build a new list.
  • Plain for-each is for reading, not removing.

🔁 for-each vs the normal for loop

Both loops can walk an array, so when do you pick which? The simple split:

  • Enhanced for when you just need the values and do not care about positions. Shorter and safer, read-only in spirit.
  • Normal for when you need the index: to change elements, go backwards, skip items, or read two arrays together.

This table sums up the trade-off:

What you need Best choice
Just read each value Enhanced for (for-each)
Know the position of each item Normal for
Change array elements Normal for
Go backwards or skip items Normal for
Loop two arrays side by side Normal for

You cannot get the index in a for-each

The enhanced for loop hides the index from you on purpose. So if you need to know “this is item number 3”, or you want to modify the array at a position, the for-each loop will not help. Use a normal for loop with an index for those jobs.

⚠️ Common Mistakes

A few for-each slip-ups, each with the wrong way then the fix.

Trying to use an index that is not there. A for-each has no i, so you cannot ask for a position.

for (String name : names) {
System.out.println(i + ": " + name); // ❌ no i exists here
}
for (int i = 0; i < names.length; i++) {
System.out.println(i + ": " + names[i]); // ✅ normal for gives you i
}

Wrong element type. The type before the variable must match the elements. The items in an int[] are int, not String.

int[] marks = {85, 90, 78};
for (String m : marks) { // ❌ will not compile, items are int
System.out.println(m);
}
for (int m : marks) { // ✅ type matches the elements
System.out.println(m);
}

Expecting changes to the loop variable to stick. For primitives the loop variable is a copy, so assigning to it does nothing to the array.

for (int n : numbers) {
n = 0; // ❌ only zeroes the copy
}
for (int i = 0; i < numbers.length; i++) {
numbers[i] = 0; // ✅ actually zeroes the array
}

Removing from a collection while you loop it. This throws a ConcurrentModificationException at runtime.

for (String city : cities) {
cities.remove(city); // ❌ crashes mid-loop
}
cities.removeIf(city -> city.equals("Tokyo")); // ✅ safe, no manual loop

✅ Best Practices

Habits for clean for-each loops:

  • Reach for it when you only need values. Reading and processing every item is what it is for.
  • Name the loop variable as a singular. name for names, mark for marks. Then it reads like plain English.
  • Switch to a normal for when you need the index. Modifying elements, going in reverse, skipping, or pairing two arrays all need an index.
  • Do not remove inside a for-each. Use removeIf, an Iterator, or build a new list.
  • Keep the body short. A for-each is meant to be easy to read.

🧩 What You’ve Learned

Nicely done. Quick recap:

  • ✅ The enhanced for loop (for-each) goes through every item in an array or collection without an index.
  • ✅ The syntax reads as “for each item in collection”: for (Type item : collection), where the : means “in”.
  • ✅ It works on arrays and any Iterable, like List and Set.
  • ✅ It is shorter and safer than a normal for because there is no counter to manage.
  • ✅ Its limits: no index, you cannot change a primitive element through the loop variable, you cannot remove while looping, and you cannot easily go backwards or pair two arrays.
  • ✅ Use a normal for loop when you need the index, want to modify elements, or go backwards.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    What does the enhanced for loop give you on each pass?

    Why: A for-each loop hands you each value one at a time, with no index involved.

  2. 2

    How do you read the loop `for (String name : names)`?

    Why: The colon means 'in', so it reads 'for each name in names'.

  3. 3

    When should you use a normal for loop instead of a for-each?

    Why: The for-each hides the index, so anything needing positions or element changes needs a normal for loop.

  4. 4

    What happens if you assign a new value to the loop variable in `for (int n : numbers)`?

    Why: For primitives the loop variable is a copy, so changing it does not touch the original array.

🚀 What’s Next?

Sometimes you need to stop a loop early, before it would normally finish. Like when you find what you were searching for. Java has a keyword just for that: break. Let’s see how it works.

Java break Statement

Share & Connect