Unit 4 · 15 min

4.12 2D Array Traversals

The loop on the outside decides the order; arr[row][col] never changes its shape.

Summary, objectives and course and exam description (CED) codes

Nested loops traverse a two-dimensional (2D) array: in row-major order the outer loop picks a row and the inner loop moves across it; in column-major order the outer loop picks a column and the inner loop moves down it. In a nested enhanced for loop the outer variable is a row (a one-dimensional (1D) array) and the inner variable is one element, and assigning to that variable does not change the array.

By the end of this session you can

  • 4.12.A Develop code used to traverse the elements in a 2D array and determine the result of these traversals.

4.12.A4.12.A.14.12.A.2

Reviewed against the CED on

Know this already? Jump to the checkpoint.

1LearnThe notes, the traps and how to remember them

1. Row-major order: across each row

Nested iteration statements visit every element of a 2D array 4.12.A.1. In row-major order the traversal moves across each row: the outer loop picks a row and the inner loop visits every column of that row 4.12.A.1.

int[][] grid = { {1, 2, 3},
                 {4, 5, 6} };
for (int r = 0; r < grid.length; r++)          // rows: slow
{
    for (int c = 0; c < grid[0].length; c++)   // columns: fast
    {
        System.out.print(grid[r][c] + " ");
    }
    System.out.println();
}

Output:

1 2 3 
4 5 6 

Visit order (each cell shows when it is visited):

col 0 col 1 col 2
row 0 1st 2nd 3rd
row 1 4th 5th 6th

2. Column-major order: down each column

In column-major order the traversal moves down each column 4.12.A.1. Put the column loop outside and the row loop inside. The bounds swap too, but the element is still grid[r][c].

int[][] grid = { {1, 2, 3},
                 {4, 5, 6} };
for (int c = 0; c < grid[0].length; c++)       // columns: slow
{
    for (int r = 0; r < grid.length; r++)      // rows: fast
    {
        System.out.print(grid[r][c] + " ");
    }
}
System.out.println();

Output:

1 4 2 5 3 6 
col 0 col 1 col 2
row 0 1st 3rd 5th
row 1 2nd 4th 6th

Watch out: if you keep r < grid[0].length as the inner bound, then on this 2 by 3 array r reaches 2 and grid[2][0] throws an ArrayIndexOutOfBoundsException.

3. Uniquely defined orders and parts of the array

Nested loops can also visit elements in an order you define, or only an ordered sequence of them 4.12.A.1. Change where a loop starts, where it stops and how it steps.

int[][] grid = { {1, 2, 3},
                 {4, 5, 6},
                 {7, 8, 9} };

// bottom row to top row, right to left
for (int r = grid.length - 1; r >= 0; r--)
{
    for (int c = grid[0].length - 1; c >= 0; c--)
    {
        System.out.print(grid[r][c] + " ");
    }
}
System.out.println();

// main diagonal only: one loop is enough
for (int i = 0; i < grid.length; i++)
{
    System.out.print(grid[i][i] + " ");
}
System.out.println();

// zigzag: even rows left to right, odd rows right to left
for (int r = 0; r < grid.length; r++)
{
    if (r % 2 == 0)
    {
        for (int c = 0; c < grid[r].length; c++)
        {
            System.out.print(grid[r][c] + " ");
        }
    }
    else
    {
        for (int c = grid[r].length - 1; c >= 0; c--)
        {
            System.out.print(grid[r][c] + " ");
        }
    }
}
System.out.println();

Output:

9 8 7 6 5 4 3 2 1 
1 5 9 
1 2 3 6 5 4 7 8 9 

Tip for tracing: write the values of r and c in the order the loops produce them, then read the grid at each pair.

4. Nested enhanced for loops

Because a 2D array is an array of arrays, an enhanced for loop works on it the same way as on a 1D array 4.12.A.1. The outer loop visits the rows, so its variable must have the row type, a 1D array. The inner loop visits one row, so its variable has the element type 4.12.A.2.

2D array type Outer variable (a row) Inner variable (an element)
int[][] int[] row int value
double[][] double[] row double value
String[][] String[] row String value
String[][] teams = { {"Ada", "Bo"},
                     {"Cy", "Dee"},
                     {"Eli", "Fay"} };
int letters = 0;
for (String[] row : teams)
{
    for (String name : row)
    {
        letters += name.length();
    }
}
System.out.println(letters + " letters");

Output:

16 letters

A nested enhanced for loop always visits elements in row-major order, and it gives no indexes. Use indexed loops when you need column-major order or the position of an element.

5. Assigning to the loop variable does not change the array

The enhanced for loop variable gets a copy of each element value. Assigning a new value to it does not change the value stored in the array 4.12.A.2.

int[][] marks = { {3, 7},
                  {5, 9} };
for (int[] row : marks)
{
    for (int m : row)
    {
        m = 0;               // changes only the copy
    }
}
System.out.println(marks[0][0] + " " + marks[1][1]);

for (int r = 0; r < marks.length; r++)
{
    for (int c = 0; c < marks[0].length; c++)
    {
        marks[r][c] = 0;     // changes the array
    }
}
System.out.println(marks[0][0] + " " + marks[1][1]);

Output:

3 9
0 0

Background: the outer variable row refers to the real row, so row[0] = 0; inside the outer loop would change the array. Assigning to the inner variable m never does.

Lock it in: memory hooks

  • Row-major orderRead a book: left to right across a line, then drop to the next line.
  • Column-major orderRead a newspaper column: top to bottom, then move one column right.
  • Whichever loop is outsideThe outer loop moves slowly, the inner loop moves fast. The slow index names the order.

Common misconceptions

  • "Swapping the two for loop headers is enough to switch to column-major order."

    Not quite. You must also swap the bounds: the outer loop now runs over columns (arr[0].length) and the inner loop over rows (arr.length). Keeping the old bounds causes an ArrayIndexOutOfBoundsException on a non-square array.

  • "In a nested enhanced for loop, the outer variable can be an int."

    Not quite. The outer loop visits rows, and each row is a 1D array, so for an int[][] the outer variable must be int[]. The inner variable is int.

  • "Setting the enhanced for loop variable to 0 clears the element."

    Not quite. The loop variable holds a copy of the element's value. Assigning a new value to it changes only the copy, not the array.

Exam traps

  • In column-major order the access is still arr[r][c], not arr[c][r].
  • Column-major loops bound the outer loop by arr[0].length and the inner loop by arr.length.
  • for (int[] row : arr) { for (int x : row) { x = 0; } } leaves the array unchanged.
  • The outer enhanced for variable of a String[][] is a String[], not a String.

2PracticeRecall it, then check yourself

In 30 seconds

  1. Nested loops visit every element of a 2D array, or an ordered part of it.
  2. Row-major: outer loop over rows (r < arr.length), inner over columns (c < arr[0].length).
  3. Column-major: outer loop over columns (c < arr[0].length), inner over rows (r < arr.length); the access is still arr[r][c].
  4. Nested enhanced for: for (int[] row : arr) then for (int x : row).
  5. Assigning to an enhanced for loop variable never changes the array; use indexes to change elements.

Cover this list, say the points out loud, then take the checkpoint without scrolling back up.

Checkpoint · 4 questions

Checkpoint: 2D Array Traversals

Pick an answer to mark it. Every answer is explained, and you can try any question again. Your saved score counts first tries only, and stays in this browser.

  1. 1 Consider the following code segment. What is printed as a result of executing the code segment? 4.12.A.1
    int[][] vals = { {1, 2, 3},
                     {4, 5, 6} };
    for (int c = 0; c < vals[0].length; c++)
    {
        for (int r = 0; r < vals.length; r++)
        {
            System.out.print(vals[r][c] + " ");
        }
    }
    Show answer

    Answer: C. The outer loop runs over columns and the inner loop over rows, so the traversal is in column-major order: down column 0 (1, 4), then column 1 (2, 5), then column 2 (3, 6). 1 2 3 4 5 6 is row-major order, 3 6 2 5 1 4 starts from the last column, and 1 3 5 2 4 6 reads the values as if the array had 3 rows of 2.

  2. 2 Consider the following code segment. What is printed as a result of executing the code segment? 4.12.A.2
    int[][] m = { {1, 2},
                  {3, 4} };
    for (int[] row : m)
    {
        for (int v : row)
        {
            v *= 2;
        }
    }
    int sum = 0;
    for (int[] row : m)
    {
        for (int v : row)
        {
            sum += v;
        }
    }
    System.out.println(sum);
    Show answer

    Answer: A. In the first nested loop, v holds a copy of each element, so v *= 2 changes only the copy and the array keeps 1, 2, 3 and 4. The second loop adds them: 10. 20 assumes the elements were doubled, and 0 and 14 assume other changes to the array.

  3. 3 The following code segment is intended to print the elements of vals in column-major order. What is the result of executing the code segment? 4.12.A.1
    int[][] vals = { {1, 2, 3},
                     {4, 5, 6} };
    for (int c = 0; c < vals.length; c++)
    {
        for (int r = 0; r < vals[0].length; r++)
        {
            System.out.print(vals[r][c] + " ");
        }
    }
    Show answer

    Answer: D. The loop headers were swapped but the bounds were not. The outer loop runs c from 0 to 1 (vals.length is 2) and the inner loop runs r from 0 to 2 (vals[0].length is 3). After printing vals[0][0] and vals[1][0], the access vals[2][0] throws an ArrayIndexOutOfBoundsException. The code compiles, because index errors are only found when the program runs.

  4. 4 A nested enhanced for loop traverses the 2D array String[][] seats. Which of the following is a correct header for the outer loop? 4.12.A.2
    Show answer

    Answer: B. The outer loop visits the rows of the 2D array, and each row is a 1D array of String, so the variable must be String[]. String is the type of the inner loop variable, String[][] is the type of the whole array, and an int cannot hold a row.

3PrevailLock it in for exam day

By the numbers

Name each list from memory, then reveal it to check. Each list shows how many items to recall.

  • Orders a nested traversal can follow three orders CED 4.12.A.1
    1. row-major orderacross each row
    2. column-major orderdown each column
    3. a uniquely defined orderfor example backward, a diagonal or a zigzag
  • Variable types in a nested enhanced for loop over an int[][] two variables CED 4.12.A.2
    1. outer loop variableint[] (one row)
    2. inner loop variableint (one element)

Key terms: flip the cards

Read the term, say the definition out loud, then flip to check. Struggling a little to remember is what makes it stick.

  • 2D arraytap to flip

    An array of arrays that stores related data in rows and columns; each element is reached with arr[row][col].

    Example and CED codes
  • Row-major ordertap to flip

    A 2D array traversal that moves across each row, left to right, before going down to the next row.

    Example and CED codes
  • Column-major ordertap to flip

    A 2D array traversal that moves down each column, top to bottom, before moving to the next column.

    Example and CED codes
  • Traversaltap to flip

    Using repetition (or recursion) to access all elements of an array or ArrayList, or an ordered sequence of them.

    Example and CED codes
  • for looptap to flip

    An iterative statement whose header has three parts: the initialization (runs once), the Boolean expression (checked before each iteration) and the update (after each iteration).

    Example and CED codes
  • Arraytap to flip

    An object that stores a fixed number of values of the same type, either primitive values or object references, reached by an index.

    Example and CED codes

Questions students ask

What is the difference between row-major and column-major order?

Row-major order visits all elements of row 0 from left to right, then row 1, and so on. Column-major order visits all elements of column 0 from top to bottom, then column 1, and so on.

How do you traverse a 2D array with an enhanced for loop in Java?

Use two enhanced for loops: the outer variable is a row (a 1D array such as int[] row) and the inner variable is one element of that row (such as int value). This always visits elements in row-major order.

Can an enhanced for loop change the values in a 2D array?

Not by assigning to the loop variable. The variable is a copy of the element value, so use indexed for loops (arr[r][c] = ...) to change elements.

How do you traverse a 2D array column by column?

Put the column loop outside: for (int c = 0; c < arr[0].length; c++) and inside it for (int r = 0; r < arr.length; r++), then access arr[r][c].

Was this page helpful?

No names are ever shown, and every public comment is checked by us first. Please do not include personal details. To get a reply, email [email protected].

↑ Top

Enlarged view of the selected figure