Java Nested Loops and Enhanced for Loops

A nested loop places one loop inside another.

Lesson 24 of 127Beginner14 min read

A nested loop places one loop inside another. It is useful for working with rows and columns or combining every item from two groups. An enhanced for loop reads each element of an array or Iterable without exposing a numeric index. These forms solve different problems: nesting describes repeated groups, while enhanced for simplifies element traversal.

Before writing either form, describe what one iteration means. In a grid, the outer iteration usually selects a row and the inner iteration visits its cells. In a single enhanced loop, each iteration receives the next element.

Follow the outer and inner sequence

For each outer iteration, Java runs the entire inner loop from its initialization to its completion. Only then does the outer loop advance. A two-row, three-column grid therefore visits six positions when every row has three cells. The inner counter is initialized again for each row, not carried forward from the previous row.

This execution order explains row-major traversal: all columns of the first row are processed before the second row starts. Reversing the loops changes the visit order, which may matter for output and access patterns. Do not assume a nested loop is always quadratic. Its work depends on the iteration counts: rows times columns, or the sum of actual row lengths when those lengths vary.

Use indexes when position matters

A traditional indexed for loop gives access to the position as well as the element. Use it when you need a neighboring element, a coordinate, an index in a message or an assignment to a particular array position. The valid indexes of each array run from zero to its length minus one.

Java multidimensional arrays are arrays of arrays, so rows can have different lengths. For a jagged grid, use grid[row].length as the inner boundary rather than assuming every row has the first row’s length. A null row needs separate handling before accessing its length. This lesson uses nonnull rows, but the assumption should be explicit whenever arrays come from external code.

Enhanced for reads elements directly

The enhanced form for (int value : numbers) assigns the next array element to a loop variable on each iteration. You do not initialize an index or write an update expression. It works for arrays and objects implementing Iterable, including many collection types.

This is often the clearest form when you only need the values. It does not directly supply the element’s index, and assigning a different value to the loop variable does not replace the corresponding array element. For primitive arrays, the variable contains a copy of the primitive value. To update array positions, use an indexed loop. A separately maintained counter can accompany enhanced for, but if position is central to the task an indexed loop communicates that intent better.

References inside enhanced loops

For an array or collection of objects, the loop variable receives a copy of each reference. Calling a mutating method through that reference can change the referenced object. Reassigning the loop variable to another object does not replace the element held by the original array or collection.

These are two different operations: changing an object and changing which object a slot refers to. The same distinction appears with ordinary method parameters. For example, appending to a StringBuilder received during traversal changes that builder, while assigning the variable to a new builder leaves the original slot unchanged. For String elements, methods return new strings because String is immutable; simply calling toUpperCase without storing the result does not revise the collection.

Collection changes during traversal

Do not structurally modify an ordinary ArrayList with its add or remove methods inside an enhanced loop over that list. Its iterator commonly detects that modification and throws ConcurrentModificationException. This is a bug-detection mechanism, not a promise that every misuse is detected or a synchronization solution.

If you need removal during traversal, use an iterator’s supported remove operation or an appropriate bulk operation such as removeIf. Arrays have fixed length and a different set of update possibilities. Choose a traversal based on the operation you need rather than replacing every loop with the shortest syntax. For nested enhanced loops over rows, you gain readable values but still need indexes when output must include coordinates.

Practice with explained solutions

Task 1. Count the elements in rows of lengths two, one and three using nested enhanced loops.

Solution. Increase a counter once per visited element. The result is six; no fixed column count is needed.

Task 2. Double every integer stored in an array, retaining the results in the same array.

Solution. Use an indexed loop and assign back to each array slot. An enhanced loop that only reassigns its primitive variable will not retain the changes.

Java Summary

  • Use each current row's length when traversing jagged arrays.
  • Enhanced for is convenient when values matter more than indexes.
  • Reassigning its loop variable does not replace an array slot, although mutating a referenced object can change that object.
  • Continue with break and continue.

Java Examples

Each example shows the code, the output it produces and what each part does.

Example 1

Visit every grid coordinate

Save this complete program as GridCoordinates.java. Compile with javac --release 17 GridCoordinates.java and run with java GridCoordinates.

Java
public class GridCoordinates {
    public static void main(String[] args) {
        int[][] grid = {{4, 7}, {9, 2}};
        for (int row = 0; row < grid.length; row++) {
            for (int column = 0; column < grid[row].length; column++) {
                System.out.println(row + "," + column + ": " + grid[row][column]);
            }
        }
    }
}
Output
0,0: 4
0,1: 7
1,0: 9
1,1: 2
Line-by-line explanation
  1. Lines 1 to 10The outer counter selects row zero first. The inner loop prints both cells in that row before row becomes one. Using the current row’s length makes the boundary valid even if later rows have different sizes. The coordinate labels come from indexes; an enhanced loop alone would not provide those positions.
Example 2

Sum values without an index

Save this complete program as EnhancedSum.java. Compile with javac --release 17 EnhancedSum.java and run with java EnhancedSum.

Java
public class EnhancedSum {
    public static void main(String[] args) {
        int[] quantities = {3, 5, 2};
        int total = 0;
        for (int quantity : quantities) {
            total += quantity;
        }
        System.out.println(total);
    }
}
Output
10
Line-by-line explanation
  1. Lines 1 to 10Each iteration copies the next integer into quantity and adds it to total. The loop needs no position because every element receives the same operation. Initializing total outside preserves the sum across all three iterations. An empty array would execute no iterations and leave total at zero, which is the natural identity for this sum.
Example 3

Reassignment does not replace array elements

Save this complete program as LoopVariableCopy.java. Compile with javac --release 17 LoopVariableCopy.java and run with java LoopVariableCopy.

Java
public class LoopVariableCopy {
    public static void main(String[] args) {
        int[] values = {2, 4};
        for (int value : values) {
            value = value * 10;
        }
        System.out.println(java.util.Arrays.toString(values));
    }
}
Output
[2, 4]
Line-by-line explanation
  1. Lines 1 to 9The multiplication updates the local loop variable, not an array slot. The array therefore keeps two and four. To produce twenty and forty, use an indexed loop and assign values[index] = values[index] * 10. The example deliberately demonstrates a legal operation with no lasting array effect, rather than a compiler error.

Common Java Mistakes

Assuming every row has the same length

Do not use grid[0].length for every row without a rectangular-array guarantee. A shorter row can cause ArrayIndexOutOfBoundsException, while a longer row can leave values unvisited. Also distinguish reassignment of an enhanced-loop variable from mutation through an object reference. They can look similar at a glance but change different parts of the program’s state.

Java FAQ

Can enhanced for traverse a Map directly?

Not as a Map object itself. Traverse entrySet, keySet or values depending on what the operation needs.

Does break leave both nested loops?

An ordinary break leaves the innermost loop. A labeled break can target an enclosing loop, but keep such control flow simple and clearly justified.

How do I loop over a 2D array with enhanced for loops?

Use one enhanced loop for the rows and another for the values in each row: for (int[] row : grid) { for (int value : row) { ... } }. The outer variable holds a whole row, which is itself an array. This form also handles jagged arrays, because each inner loop uses that row's own length.

Can I get the index in an enhanced for loop?

No. The enhanced loop hides the index. If you need positions, use a classic indexed for loop, or keep a separate counter that you increase at the end of each pass. Using indexOf inside the loop is slower and gives the wrong answer when values repeat.

How many times does the body of a nested loop run?

The outer count multiplied by the inner count. Ten rows of twenty columns run the inner body 200 times, and two nested loops over the same list of n items run it n × n times. That growth is why nested loops over large collections can become slow, as the complexity lesson explains.

Java Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Multiple choiceeasy

How many cells are visited in rows of lengths 2, 1 and 3?

Multiple choicemedium

Which form can replace an array element directly?

Java Quiz

2 questions to check what you learned.

  1. Which loop is convenient when only element values are needed?

    • Enhanced for
    • An unrelated empty while
    • A loop requiring a nonexistent index
  2. What does assigning to an enhanced-loop int variable change?

    • Only the local variable
    • The original array element automatically
    • The array length