Skip to content
Theory · Arrays · lesson 7 of 8

Two-dimensional arrays

A row of lockers is good for a list: player scores, prices, grades. But a lot of data is shaped like a table. A seat in a cinema is a row and a seat number; a square on a game board is a row and a column.

In a gym, lockers often stand as a wall too: several rows one above another. To find a locker you need two numbers, the row and the place in the row. In Java such a wall is built from ordinary arrays: each row is its own array, and one more array holds tickets to all the rows.

JAVA
public class Main {
    public static void main(String[] args) {
        int[][] grid = new int[2][3];
        grid[1][2] = 7;
        System.out.println(grid[1][2]);     // 7
        System.out.println(grid[0][0]);     // 0
        System.out.println(grid.length);    // 2
        System.out.println(grid[0].length); // 3
    }
}

Let's walk through the program step by step:

  1. new int[2][3] creates a table of two rows of three elements, and every element holds 0.
  2. grid[1][2] = 7; puts 7 into the second row, the third column.
  3. grid[1][2] prints 7.
  4. grid[0][0] is the first element of the first row; nothing was put there: 0.
  5. grid.length prints 2, and grid[0].length prints 3.

An array of arrays

A two-dimensional array is an array whose elements are arrays too. The type int[][] reads as "array of arrays of int". The form new int[2][3] creates an outer array of two elements, and each element is a reference to its own row, an int[3] array.

Indices: row and column

The expression grid[1][2] reads from left to right:

  1. grid[1] takes the second row from the outer array. It is an ordinary int[].
  2. [2] takes the third element from that row.

So the first index picks the row and the second picks the column, that is, the place in the row. Both count from zero, as in any array.

Two lengths

A table has two sizes, and each comes from its own array:

  • grid.length is the length of the outer array, that is, the number of rows: 2;
  • grid[0].length is the length of the first row, that is, the number of columns: 3;
  • there are 2 * 3 elements in all, that is six, but grid.length does not count them.

Interviewers like to ask what grid.length returns for new int[2][3]. The answer is 2, the number of rows, not the number of all elements.

Looping with nested loops

A table can also be given with values right away: each pair of inner braces is one row. To go through all the elements you need two loops, one inside the other:

JAVA
int[][] table = {{1, 2, 3}, {4, 5, 6}};
int sum = 0;
for (int i = 0; i < table.length; i++) {
    for (int j = 0; j < table[i].length; j++) {
        sum = sum + table[i][j];
    }
}
System.out.println(sum); // 21

Let's see how the loops work:

  1. The outer loop goes over the rows: i runs through 0 and 1 while i < table.length.
  2. The inner loop goes over the columns of the current row: j runs through 0, 1 and 2 while j < table[i].length.
  3. For each row the inner loop runs all the way through, so the body runs six times.
  4. sum collects all six elements and prints 21.

Here the locker-wall picture is off. In a real wall all rows have the same length, while in Java each row is a separate array, and rows can have different lengths: {{1, 2}, {3, 4, 5}}. That is why in the inner loop it is safer to write table[i].length, the length of the current row.

Printing a table

Arrays.toString prints one array, so for a table it only covers a single row. The whole table is printed by Arrays.deepToString:

JAVA
System.out.println(Arrays.toString(table[1]));  // [4, 5, 6]
System.out.println(Arrays.deepToString(table)); // [[1, 2, 3], [4, 5, 6]]

If you pass the whole table to Arrays.toString, it prints not numbers but service notes like [I@ for each row. The elements of the outer array are references, and toString prints them. The method deepToString follows each reference and prints the row itself.

Common mistake

The two lengths got swapped in the loop headers:

JAVA
int[][] table = {{1, 2, 3}, {4, 5, 6}};
int sum = 0;
for (int i = 0; i < table[0].length; i++) { // ✗
    for (int j = 0; j < table.length; j++) {
        sum = sum + table[i][j];
    }
}
TEXT
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2

The outer loop picks the row, but its bound is table[0].length, the number of columns, which is 3. On the third lap i becomes 2, while there are only two rows, with indices 0 and 1. Rows are bounded by table.length, and columns by table[i].length.

Key points

  • A two-dimensional array is an array of arrays: new int[2][3] creates two rows of three elements.
  • In grid[i][j] the first index picks the row and the second picks the column.
  • grid.length is the number of rows, and grid[0].length is the length of the first row, that is, the number of columns.
  • A table is traversed with nested loops: the outer one up to grid.length, the inner one up to grid[i].length.