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.
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:
new int[2][3]creates a table of two rows of three elements, and every element holds0.grid[1][2] = 7;puts7into the second row, the third column.grid[1][2]prints7.grid[0][0]is the first element of the first row; nothing was put there:0.grid.lengthprints2, andgrid[0].lengthprints3.
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:
grid[1]takes the second row from the outer array. It is an ordinaryint[].[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.lengthis the length of the outer array, that is, the number of rows:2;grid[0].lengthis the length of the first row, that is, the number of columns:3;- there are
2 * 3elements in all, that is six, butgrid.lengthdoes 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:
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); // 21Let's see how the loops work:
- The outer loop goes over the rows:
iruns through0and1whilei < table.length. - The inner loop goes over the columns of the current row:
jruns through0,1and2whilej < table[i].length. - For each row the inner loop runs all the way through, so the body runs six times.
sumcollects all six elements and prints21.
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:
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:
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];
}
}Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2The 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.lengthis the number of rows, andgrid[0].lengthis 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 togrid[i].length.