Java 2D arrays (matrices)
A 2D array organises values into rows and columns, like a grid or a spreadsheet. Each cell is identified by two indices: [row][column]. Tracing code that reads, writes, and loops over a 2D array is a skill that comes up in grid-based algorithms, image processing, game boards, and countless other contexts.
Core idea
A 2D array in Java is an array of arrays. The first index selects a row; the second selects a column within that row. Both indices are zero-based. The number of rows is matrix.length and the number of columns is matrix[0].length.
Declaring and initializing 2D arrays
Array literal — nest one row per inner pair of braces. Each inner array is a row.
int[][] grid = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
New keyword — specify rows then columns. Every cell starts at 0.
int[][] grid = new int[3][4]; // 3 rows, 4 cols
Indexing: rows and columns
Think of a 2D array as a table. The first bracket selects the row (top to bottom), and the second selects the column within that row (left to right).
Grid diagram for
int[][] m = {{10, 20, 30}, {40, 50, 60}, {70, 80, 90}}
col 0 col 1 col 2
row 0: 10 20 30
row 1: 40 50 60
row 2: 70 80 90
m[0][0] → 10 m[0][2] → 30
m[1][1] → 50 m[2][0] → 70
m[2][2] → 90 ← bottom-right corner
m.length → 3 (rows)
m[0].length → 3 (columns)
Modifying cells
Assigning to a cell works exactly like a 1D array, but with two indices. The original value is gone; any later read of that cell returns the new value.
int[][] grid = {{1, 2}, {3, 4}};
grid[0][1] = 99;
System.out.println(grid[0][1]); // 99, not 2
System.out.println(grid[1][0]); // 3, unchanged
Iterating with nested loops
You almost always need two nested loops to visit every cell: one for rows and one for columns within each row.
Indexed nested for loop
int[][] m = {{1, 2, 3}, {4, 5, 6}};
for (int r = 0; r < m.length; r++) {
for (int c = 0; c < m[r].length; c++) {
System.out.println(m[r][c]);
}
}
The outer loop runs for each row (r = 0, 1). The inner loop runs for each column in that row (c = 0, 1, 2). Cells are visited in reading order: 1, 2, 3, then 4, 5, 6.
Enhanced nested for-each loop
int[][] m = {{1, 2, 3}, {4, 5, 6}};
for (int[] row : m) {
for (int val : row) {
System.out.println(val);
}
}
In the outer loop, row is each inner int[] in turn. The inner loop then iterates that row's values. Output is identical: 1, 2, 3, 4, 5, 6.
Worked examples
Example 1: cell access and dimensions
int[][] mat = {{5, 10, 15}, {20, 25, 30}};
System.out.println(mat[1][2]);
System.out.println(mat.length);
System.out.println(mat[0].length);
Trace:
mat[1][2] → row 1 is {20, 25, 30}; column 2 is 30
mat.length → 2 rows
mat[0].length → 3 columns
Output:
30 2 3
Example 2: summing all cells
int[][] m = {{1, 2}, {3, 4}, {5, 6}};
int sum = 0;
for (int[] row : m) {
for (int val : row) {
sum += val;
}
}
System.out.println(sum);
Trace:
sum starts at 0
row {1,2}: sum = 0+1+2 = 3
row {3,4}: sum = 3+3+4 = 10
row {5,6}: sum = 10+5+6 = 21
Output: 21
Example 3: main diagonal
The main diagonal of a square matrix contains the cells where the row index equals the column index.
int[][] m = {{2, 4, 6}, {8, 10, 12}, {14, 16, 18}};
int sum = 0;
for (int i = 0; i < m.length; i++) {
sum += m[i][i];
}
System.out.println(sum);
Trace:
i=0: m[0][0] = 2 → sum = 2 i=1: m[1][1] = 10 → sum = 12 i=2: m[2][2] = 18 → sum = 30
Output: 30
Example 4: printing row sums
int[][] m = {{3, 7}, {1, 9}, {5, 2}};
for (int[] row : m) {
int rowSum = 0;
for (int val : row) rowSum += val;
System.out.println(rowSum);
}
Trace:
row {3, 7}: rowSum = 3+7 = 10 → prints 10
row {1, 9}: rowSum = 1+9 = 10 → prints 10
row {5, 2}: rowSum = 5+2 = 7 → prints 7
Output:
10 10 7
Refreshable sample
Try one 2D array question
Select "No loops" or "With loops", read the snippet carefully, and type what the code prints. For multi-line output, put each printed value on its own line in the text area.
Key things to remember
- Both indices are zero-based. The top-left cell is always
matrix[0][0]. -
matrix.lengthis the number of rows.matrix[0].lengthis the number of columns. - The main diagonal is accessed with a single loop:
matrix[i][i]. - A specific column can be printed with a single loop that iterates rows and reads a fixed column index.
- Nested for-each loops use
for (int[] row : matrix)as the outer loop because each row is itself an array.