Skip to content
Study Hall
Lesson 5 of 5Arrays
Unit 6 · Lesson 5 of 5

Two-Dimensional Arrays

Rows and columns: declaring a grid, reaching a cell with two indexes, and walking the whole thing with nested loops.

7 min read11 practice questionsInteractiveAsk AI about this →

Key things to remember

  1. 1int[][] grid = new int[3][4]; makes 3 rows of 4 columns — 12 cells, all starting at 0.
  2. 2A cell is grid[row][col]: row first, column second, both counting from 0.
  3. 3grid.length is the number of rows; grid[0].length is the number of columns.
  4. 4Nested loops traverse a grid — outer loop over rows, inner loop over columns.
  5. 5The inner body runs rows times columns times in total, so a 3 by 4 grid means 12 passes.
  6. 6Java stores grids in row-major order: all of row 0, then all of row 1, and so on.

A one-dimensional array is a row of boxes. Plenty of real data is not a row — it is a table. A seating chart has rows and seats within a row, a spreadsheet has rows and columns, a game board has squares in both directions, and a mark book has one row per student and one column per assignment. For any of these, a two-dimensional array lets you name a single value by saying which row and which column it is in.

// 3 rows, 4 columns - 12 slots, all starting at 0
int[][] grid = new int[3][4];

// You can also write the values out directly.
// Each inner set of braces is one ROW.
int[][] table = {
    {1, 2, 3},
    {4, 5, 6}
};                       // 2 rows, 3 columns

// The element type does not have to be int - a seating chart is a String grid
String[][] seats = new String[2][3];   // every cell starts as null
Two pairs of brackets in the type mean two indexes are needed to reach a value.
A 2-D array is an array of rows, and each row is itself an array.int[][] grid = new int[3][4]; // 3 rows, 4 columnscol 0col 1col 2col 3row 0row 1row 2[0][0][0][1][0][2][0][3][1][0][1][1][1][2][1][3][2][0][2][1][2][2][2][3]grid.length3 — the number of rowsgrid[0].length4 — the length of one rowgrid[2][3]the last cell of allRow index first, column index second — grid[row][col]. Swapping them is the usual bug.To visit every cell you need nested loops: the outer over rows, the inner over the columns of that row.
Fig 1A grid of three rows and four columns, with each cell labelled by its row and column index.

A single element is written grid[row][col], and the order is fixed: row first, column second. Both indexes are zero-based, so the top-left cell is grid[0][0] and in a three-by-four grid the bottom-right cell is grid[2][3]. Swapping the two indexes usually still compiles, which is the problem — grid[3][2] on a three-by-four grid throws, and on a square grid it quietly reads the wrong cell instead.

ExpressionMeaning for int[][] grid = new int[3][4]
grid[0][0]Top-left cell — the first column of the first row
grid[2][3]Bottom-right cell — row index 2, column index 3
grid[1]The whole second row, itself an int[] of length 4
grid.length3 — the number of ROWS
grid[0].length4 — the number of columns in row 0
grid[3][0]Throws — there is no row 3, only rows 0, 1 and 2
Two lengths, and they mean different things
grid.length counts the rows, because a two-dimensional array is really an array of rows. To count the columns you must look inside a row: grid[0].length. Getting these the wrong way round is the most common two-dimensional bug, and on a square grid it produces no error at all — just wrong answers.
public class GridDemo {
    public static void main(String[] args) {
        int[][] grid = new int[3][4];

        grid[0][0] = 5;
        grid[2][3] = 9;

        System.out.println(grid.length);      // 3  - rows
        System.out.println(grid[0].length);   // 4  - columns
        System.out.println(grid[1][2]);       // 0  - never assigned, still the default
        System.out.println(grid[2][3]);       // 9
    }
}

To visit every cell you need two loops, one inside the other. The outer loop picks a row and the inner loop walks the columns of that row, so the inner loop runs completely for every single pass of the outer loop. That is why a three-by-four grid takes twelve passes of the inner body: three rows times four columns. Bound the inner loop with grid[row].length rather than a fixed number, and the code stays correct if the grid changes shape.

int[][] table = {
    {1, 2, 3},
    {4, 5, 6}
};

for (int row = 0; row < table.length; row++) {
    for (int col = 0; col < table[row].length; col++) {
        System.out.print(table[row][col] + " ");
    }
    System.out.println();     // end the line AFTER the inner loop finishes
}
Output is two lines: 1 2 3 then 4 5 6.
Where the line break goes decides the shape of the output
The bare println belongs between the two closing braces — inside the outer loop but outside the inner one. Put it inside the inner loop and every value lands on its own line. Put it after both loops and the whole grid prints as one long line. The indentation is not decoration; it is the difference between a table and a mess.
The inner loop finishes completely for every single pass of the outer loop.for (int r = 0; r < 3; r++) { for (int c = 0; c < 4; c++) { System.out.print("*"); } System.out.println();}c=0c=1c=2c=3r=0r=1r=210,020,130,240,351,061,171,281,392,0102,1112,2122,33 outer × 4 inner = 12 runs of the bodyThe numbers show the visit order: the whole first row, then the whole second row, then the third.Total passes = outer count × inner count, so adding one row here adds four more runs, not one.
Fig 2The outer loop counts rows while the inner loop sweeps across each row in turn.
public class TimesTable {
    public static void main(String[] args) {
        int[][] times = new int[4][4];

        for (int r = 0; r < times.length; r++) {
            for (int c = 0; c < times[r].length; c++) {
                times[r][c] = (r + 1) * (c + 1);
            }
        }

        System.out.println(times[0][0]);   // 1  = 1 x 1
        System.out.println(times[2][3]);   // 12 = 3 x 4
        System.out.println(times[3][3]);   // 16 = 4 x 4
    }
}
Nested loops build a table as easily as they read one. The plus ones turn zero-based indexes into the numbers a person expects.

Plenty of questions ask for a single row or a single column rather than the whole grid, and the two look pleasingly different in code. For one row, hold the row index fixed and loop the column. For one column, hold the column index fixed and loop the row — and note the loop bound changes to table.length, because you are now counting rows. Behind all of this is row-major order: memory is one long line of addresses, so Java lays out the whole of row 0 first, then the whole of row 1, and so on. That is why grid[1] is a complete int[] you can pass to a method on its own, and why rows may legally have different lengths.

int[][] table = {
    {1, 2, 3},
    {4, 5, 6}
};

// Total of row 1: 4 + 5 + 6 = 15
int rowTotal = 0;
for (int col = 0; col < table[1].length; col++) {
    rowTotal += table[1][col];
}

// Total of column 2: 3 + 6 = 9
int colTotal = 0;
for (int row = 0; row < table.length; row++) {
    colTotal += table[row][2];
}

System.out.println(rowTotal + " " + colTotal);   // 15 9
The fixed index names what you are summing; the varying index is the one you loop.
Loading interactive…
Step through a nested loop one statement at a time and watch both index variables change.
Tracing by hand is how you find a logic error the computer will not report.total = 0i = 1while i <= 4: total = total + i i = i + 1itotalpasscondition—00—1111 ≤ 4 true2322 ≤ 4 true3633 ≤ 4 true41044 ≤ 4 true51055 ≤ 4 FALSE — exitFinal total = 10One row per pass.Write down everyvariable, every time.Forget the i = i + 1 line andthe table never ends: infinite loop.
Fig 3One row per pass of the inner loop, with a column for each index and for the cell being read.

Worked examples

Reveal one step at a time and try to beat it to the next line.

Example 1
For int[][] g = new int[5][3]; state the number of rows, the number of columns, the total number of cells, the value of g[4][2], and what g[2][4] does.
Example 2
Write nested loops that print the sum of each row of int[][] scores on its own line.
Example 3
Trace this and state the output: int[][] t = {{2, 4}, {6, 8}, {10, 12}}; int s = 0; for (int r = 0; r < t.length; r++) { s += t[r][1]; } System.out.println(s);

Where marks get lost

  • Writing grid[col][row] instead of grid[row][col] — on a square grid this reads the wrong cell with no error at all.
  • Using grid.length when you meant the number of columns. Columns come from grid[0].length.
  • Putting the bare System.out.println() inside the inner loop, so every value prints on its own line.
  • Declaring a per-row total outside the outer loop, so each line reports a running grand total instead.
  • Forgetting that a String[][] starts full of null, then calling a method on an unassigned cell and getting a NullPointerException.

Flashcards 9

How do you declare a grid of 3 rows and 4 columns of ints?
What does grid[2][1] mean?
How do you get the number of rows?
How do you get the number of columns?
+ 5 more

Practice

1
For int[][] g = new int[6][4]; what does g.length return?
2
For int[][] g = new int[6][4]; how many cells does the grid contain in total?
3
Which expression gives the number of columns in int[][] grid?
4
In seats[2][5], what do the two numbers mean?
5
After filling int[][] t = new int[4][4]; with t[r][c] = (r + 1) * (c + 1); what is t[2][3]?
6
For int[][] t = {{1, 2, 3}, {4, 5, 6}}; what is the total of column 2?
7
What is the name of the storage order in which all of row 0 is laid out before row 1?
8
Order these lines to print a grid as a table, one row per line.
  1. 1System.out.println();
  2. 2} closing the inner loop
  3. 3System.out.print(g[row][col] + " ");
  4. 4for (int row = 0; row < g.length; row++) {
  5. 5for (int col = 0; col < g[row].length; col++) {
9
Match each expression to what it refers to for int[][] g = new int[3][5];
g.length
g[0].length
g[1]
g[2][4]
10
A student writes the row total as int total = 0; before the OUTER loop. What goes wrong?
11
What does String[][] board = new String[3][3]; contain immediately after creation?

Spot a mistake on this page? Let us know