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 nullA 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.
| Expression | Meaning 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.length | 3 — the number of ROWS |
grid[0].length | 4 — the number of columns in row 0 |
grid[3][0] | Throws — there is no row 3, only rows 0, 1 and 2 |
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
}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
}
}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