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.
Reviewed against the CED on
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
- Nested loops visit every element of a 2D array, or an ordered part of it.
- Row-major: outer loop over rows (r < arr.length), inner over columns (c < arr[0].length).
- Column-major: outer loop over columns (c < arr[0].length), inner over rows (r < arr.length); the access is still arr[r][c].
- Nested enhanced for: for (int[] row : arr) then for (int x : row).
- 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.
3PrevailLock it in for exam day
By the numbers
- Orders a nested traversal can follow three orders CED 4.12.A.1
- row-major orderacross each row
- column-major orderdown each column
- 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
- outer loop variableint[] (one row)
- 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].