Java • Control Flow

For-Each Loops — Use enhanced for-each loops to iterate over arrays/collections

Simplify iteration by letting Java handle the indexing so you can focus on each element directly.

Java programming emblem with a coffee cup, code braces, and terminal
Inside this lesson 10 sections 5 questions 7 figures

SECTION 1

Historical Context & Motivation

From the earliest days of programming, developers needed a way to process every item in a list or array one at a time. The classic for loop using an index variable (like for (int i = 0; i < arr.length; i++)) served this purpose well, but it required programmers to manage the index manually. A single typo in the loop bounds could cause an ArrayIndexOutOfBoundsException or silently skip elements. As Java matured, the language designers realized they could offer a cleaner, safer alternative.

1996 • Java 1.0 — Classic For Loop

Java launched with the traditional C-style for loop as the primary way to iterate over arrays. Programmers managed an index variable, a boolean condition, and an increment expression.

1998 • Java 1.2 — Collections Framework

The Collections Framework introduced Iterator objects to traverse lists, sets, and maps. Iterating was safer but still verbose, requiring calls to hasNext() and next().

2004 • Java 5 — The Enhanced For-Each Loop

Java 5 (also called J2SE 5.0) introduced the enhanced for-each loop, allowing programmers to iterate over arrays and any class implementing the Iterable interface without managing indices or iterators.

2014 • Java 8 — forEach with Lambdas

Java 8 added the forEach() method using lambda expressions, providing yet another way to process each element. The enhanced for-each loop remained the most common approach for simple iteration in everyday code.

The central question the for-each loop answers is simple: How can we visit every element in a collection without worrying about where it lives or how long the collection is? This question drives the rest of this lesson.

SECTION 2

Core Principles & Definitions

The enhanced for-each loop is a control-flow statement that automatically walks through every element of an array or collection, assigning each element to a temporary variable one at a time. Its general syntax is for (Type element : collection). The colon : can be read as "in," so the statement reads like "for each element in collection, do something." Understanding this loop rests on a handful of foundational ideas.

1

No Index Required

You never declare or update a counter variable. Java handles the internal position tracking, removing a whole category of off-by-one bugs.
2

Read-Only Access

The loop variable is a copy of each element (for primitives) or a copy of the reference (for objects). Reassigning the loop variable does not change the original array or collection.
3

Works with Arrays & Iterables

The for-each loop works on any Java array and any class that implements the Iterable<T> interface, including ArrayList, HashSet, and LinkedList.
4

Forward-Only Traversal

The for-each loop always starts at the first element and moves forward to the last. You cannot skip elements, go backwards, or start in the middle.
✦

KEY TAKEAWAY

Think of the for-each loop like a conveyor belt at a sushi restaurant. Each plate (element) comes to you one at a time, and you inspect or eat it without ever needing to know which slot number it came from. The belt handles the order — you just focus on the plate in front of you. That is exactly what the for-each loop does: it delivers each element to your loop variable automatically, freeing you from managing the belt's position.

SECTION 3

Visual Explanation — How the For-Each Loop Executes

For-Each Loop — Step-by-Step Array Traversalint[] scores = {90, 85, 72, 98, 61};for (int s : scores) { ... }90[0]85[1]72[2]98[3]61[4]Iteration 1: s = 90Iteration 2: s = 85Iteration 3: s = 72Iteration 4: s = 98Iteration 5: s = 61
Each colored box in the array corresponds to one pass through the loop. The variable s receives the value of each element in order — you never write scores[i]. Notice the index labels ([0]–[4]) are shown only for reference; the for-each loop hides them entirely.

In the diagram above, the array scores contains five integers. The for-each loop starts at index 0 and assigns 90 to s, executes the loop body, then advances to index 1 and assigns 85 to s, and so on until it has visited every element. Once the last element (61) has been processed, the loop terminates automatically. The key insight is that the programmer never declares, increments, or checks a counter — Java does all of that behind the scenes.

SECTION 4

How It Works Under the Hood

The for-each loop is sometimes called "syntactic sugar" — it is a convenient shorthand that the Java compiler translates into a longer, equivalent form before the program runs. Understanding this translation helps you see exactly what the loop does and when it is appropriate.

Translation for Arrays

When you write a for-each loop over an array, the compiler converts it into a traditional indexed for loop. The code for (int s : scores) { System.out.println(s); } becomes the following behind the scenes:

ARRAY TRANSLATION

for(inti=0;i<scores.length;i++)ints=scores[i];System.out.println(s);for (int i = 0; i < scores.length; i++) { int s = scores[i]; System.out.println(s); }

The compiler creates a hidden index variable i that starts at 0, checks against scores.length, and increments by 1 each pass. The loop variable s is assigned the current element before the loop body executes.

Translation for Collections

When you use a for-each loop with a collection like ArrayList<String>, the compiler translates it into an Iterator-based while loop:

COLLECTION TRANSLATION

Iterator<String>it=names.iterator();while(it.hasNext())Stringname=it.next();System.out.println(name);Iterator<String> it = names.iterator(); while (it.hasNext()) { String name = it.next(); System.out.println(name); }

The compiler obtains an Iterator from the collection, then calls hasNext() before each iteration and next() to retrieve the element. You never see this code — the for-each syntax hides it.

⚠

Important Detail

Because the loop variable receives a copy of each value (for primitives like int or double), writing s = 100; inside the loop does not change the original array. If you need to modify elements, you must use a traditional indexed for loop.

SECTION 5

Syntax Breakdown & Common Patterns

Let's break the for-each syntax into its three essential parts and then look at common usage patterns across different data types.

Anatomy of a For-Each Loopfor(Stringname:names) { System.out.println(name);}KEYWORDfor — starts the loopDATA TYPEMust match element typeLOOP VARIABLEHolds current elementCOLON ( : )Read as "in"ARRAY / COLLECTIONSource of elementsRead: "For each String name in names, print name."
The five color-coded parts of the for-each statement: the keyword for, the data type, the loop variable, the colon (read as "in"), and the source array or collection.

Common Patterns

PatternCode ExampleNotes
Iterate over int arrayfor (int n : nums) { ... }Loop variable type must be int
Iterate over String arrayfor (String s : words) { ... }Works with any object type
Iterate over ArrayListfor (Double d : prices) { ... }Use wrapper type (Double) for generic collections
Sum all elementsint sum = 0; for (int n : nums) { sum += n; }Accumulator pattern — very common
Find a matchfor (String s : list) { if (s.equals(target)) ... }Linear search using for-each

Common for-each loop patterns in Java

SECTION 6

Worked Example — Computing a Class Average

Suppose you have an array of test scores and need to compute the class average. We will use a for-each loop to sum the scores, then divide by the number of students. This is a classic accumulator pattern — one of the most common uses of for-each loops.

Computing the Average of an Integer Array

  1. 1

    Step 1 — Declare the Array

    Start by creating an integer array with the test scores: int[] scores = {90, 85, 72, 98, 61};. This array has 5 elements.
  2. 2

    Step 2 — Initialize an Accumulator

    Before the loop, declare a variable to hold the running total: int sum = 0;. This variable starts at zero and will grow as we add each score.
    sum = 0
  3. 3

    Step 3 — Write the For-Each Loop

    Use the enhanced loop to iterate: for (int s : scores) { sum += s; }. On each pass, s takes the next score and it is added to sum. After all five iterations: sum = 0 + 90 + 85 + 72 + 98 + 61.
    sum = 406
  4. 4

    Step 4 — Compute the Average

    Divide the sum by the number of elements: double average = (double) sum / scores.length;. We cast to double so the result is not truncated by integer division. 406 ÷ 5 = 81.2.
    average = 81.2
  5. 5

    Step 5 — Print the Result

    Output the answer: System.out.println("Class average: " + average);. The complete program used no index variable, no .length check in the loop header, and no risk of going out of bounds.
    Output: Class average: 81.2

SECTION 7

For-Each vs. Traditional For Loop

The for-each loop is not a replacement for the traditional for loop — it is a specialized tool that works best in certain situations. The table below lays out the key differences so you can choose the right loop for the job.

FeatureFor-Each LoopTraditional For Loop
Index accessNo — you cannot see or use the current indexYes — the counter variable i is available
Modify elementsCannot reassign elements in the original array (primitives)Can write arr[i] = newValue;
Traverse directionForward only, from first to lastAny direction — forward, backward, skipping
ReadabilityVery high — reads like EnglishModerate — three separate clauses in header
Off-by-one riskNonePossible if bounds are wrong (e.g., <= instead of < )
PerformanceIdentical — compiler translates to the same bytecodeIdentical

Side-by-side comparison of the two loop styles

🔑

WHEN TO USE WHICH

Use the for-each loop when you need to read every element from start to finish and do not need the index. Use the traditional for loop when you need to modify elements, traverse in a non-standard order, or know the position of each element. Think of the for-each loop as a guided museum tour (you see every exhibit in order), while the traditional for loop is a self-guided visit (you choose your path).

SECTION 8

Connection to Advanced Iteration

The for-each loop is your first step toward a broader set of iteration tools in Java. As you advance, you will encounter streams and lambda expressions that build on the same idea of processing each element without managing indices. The table below previews how the for-each concept evolves.

ConceptFor-Each Loop (Java 5+)Stream API (Java 8+)
Syntaxfor (int n : nums) { ... }nums.stream().forEach(n -> ...);
FilteringRequires an if-statement inside the loop bodyBuilt-in .filter() method
TransformationBuild a new list manuallyChain .map() to transform in one line
ParallelismSingle-threaded onlySwitch to .parallelStream() for multi-core processing
DifficultyBeginner-friendlyIntermediate — requires understanding of lambdas

For-each loops vs. the Stream API

You do not need to learn streams right now — mastering the for-each loop first gives you a solid foundation. When you eventually encounter .forEach() with a lambda, it will feel like a natural extension of the same pattern: process each element, one at a time, without worrying about the index.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

Explain in your own words why the for-each loop is sometimes called a "read-only" loop for arrays of primitive types. What happens if you write element = 0; inside the loop body?
Show answer
When iterating over an array of primitives (like int or double), the loop variable receives a copy of each element's value. Assigning a new value to the loop variable (e.g., element = 0;) only changes the local copy — it does not modify the original array. This is why the for-each loop is considered read-only for primitives: you can inspect each value, but you cannot update the array through the loop variable. To modify elements, you need a traditional indexed for loop that uses arr[i] = newValue;.

Question 2: BASIC CALCULATION

Given double[] temps = {72.5, 68.3, 74.1, 69.8};, write a for-each loop that computes the sum of all temperatures and prints the result. What value is printed?
Show answer
The code is: double sum = 0; for (double t : temps) { sum += t; } System.out.println(sum);. The loop adds each value in order: 0 + 72.5 = 72.5, then 72.5 + 68.3 = 140.8, then 140.8 + 74.1 = 214.9, then 214.9 + 69.8 = 284.7. The printed value is 284.7. Notice that you never referenced an index — the for-each loop handled the traversal automatically.

Question 3: INTERMEDIATE

Write a method public static int countAbove(int[] arr, int threshold) that uses a for-each loop to count how many elements in arr are strictly greater than threshold. Trace through your method with arr = {5, 12, 8, 3, 15} and threshold = 7.
Show answer
The method is: public static int countAbove(int[] arr, int threshold) { int count = 0; for (int n : arr) { if (n > threshold) { count++; } } return count; }. Tracing with the given inputs: n=5 (5 > 7? No), n=12 (12 > 7? Yes, count=1), n=8 (8 > 7? Yes, count=2), n=3 (3 > 7? No), n=15 (15 > 7? Yes, count=3). The method returns 3. This combines the for-each loop with an accumulator pattern and a conditional check — a very common combination in real programs.

Question 4: APPLIED

A teacher stores student names in an ArrayList<String> called roster. Write a for-each loop that prints only the names whose length is greater than 5 characters. Then explain why you cannot use the for-each loop to remove students from the list during iteration and what you should use instead.
Show answer
The printing code is: for (String name : roster) { if (name.length() > 5) { System.out.println(name); } }. You cannot call roster.remove(name) inside a for-each loop because doing so modifies the collection while the hidden Iterator is still traversing it. This throws a ConcurrentModificationException. To safely remove elements during iteration, you should use an explicit Iterator and call it.remove() after it.next(), or use roster.removeIf(name -> name.length() > 5) in Java 8+.

Question 5: CRITICAL THINKING

Consider a 2D array int[][] grid = {{1, 2}, {3, 4, 5}, {6}}; (a jagged array where rows have different lengths). Write nested for-each loops to print every element. Then explain why this approach is safer than nested traditional for loops with a shared .length reference, and discuss one scenario where you would still need the traditional loop for 2D arrays.
Show answer
The nested for-each code is: for (int[] row : grid) { for (int val : row) { System.out.print(val + " "); } System.out.println(); }. This is safer than traditional nested loops because each inner for-each automatically adapts to the actual length of the current row. With traditional loops, a programmer might accidentally use grid[0].length for all rows, which would cause an ArrayIndexOutOfBoundsException on row index 2 (length 1 vs. expected 2). However, you would still need a traditional loop if you wanted to set values (e.g., grid[r][c] = r + c;) because the for-each loop variable holds a copy of the primitive value and cannot write back to the array.

SUMMARY

Lesson Summary

Summary

The enhanced for-each loop was introduced in Java 5 to simplify iteration over arrays and Iterable collections. Its syntax — for (Type variable : source) — eliminates the need for an index variable, removes off-by-one errors, and makes code easier to read. Under the hood, the compiler translates the for-each loop into either an indexed for loop (for arrays) or an Iterator-based while loop (for collections).

Use the for-each loop when you need read-only, forward-only traversal of every element. Switch to a traditional for loop when you need to modify elements, skip elements, traverse backwards, or know the current index. Common patterns include the accumulator pattern (summing values), linear search (finding a match), and nested for-each loops for 2D arrays. Mastering this loop prepares you for more advanced iteration tools like Java 8 streams and lambda expressions.

Varsity Tutors • Java • For-Each Loops — Use enhanced for-each loops to iterate over arrays/collections