2D Arrays

B2.2.2 - Construct programs that apply arrays and Lists. This page: two-dimensional (2D) arrays.


Key Concepts

A 2D array is an array of arrays - a table with rows and columns. Think of a spreadsheet, a game board, or a grade book. (Python’s equivalent is a list of lists - the same row/column picture applies.)

Declaration

// Declare with size: 3 rows, 4 columns
int[][] grid = new int[3][4];
# Python lists grow dynamically - there is no fixed-size declaration.
# A 3-row x 4-column grid of zeros, one row per line:
grid = [
    [0, 0, 0, 0],
    [0, 0, 0, 0],
    [0, 0, 0, 0]
]

All elements default to 0 (for int), false (for boolean), or null (for objects).

Initialisation with Values

int[][] matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

Accessing Elements

// Access: matrix[row][col] - row first, column second
System.out.println(matrix[1][2]);   // 6 (row 1, column 2)
matrix[0][1] = 99;                  // modify an element
# Access: matrix[row][col] - row first, column second
print(matrix[1][2])   # 6 (row 1, column 2)
matrix[0][1] = 99     # modify an element

A common mistake is swapping row and column: matrix[col][row] instead of matrix[row][col]. Always think row first, column second.

Dimensions

int rows = matrix.length;           // number of rows (3)
int cols = matrix[0].length;        // number of columns in row 0 (3)
rows = len(matrix)      # number of rows (3)
cols = len(matrix[0])   # number of columns in row 0 (3)

Visual Layout

matrix has three rows and three columns. Row 0 holds 1, 99, 3 (matrix[0][1] was changed to 99); row 1 holds 4, 5, 6; row 2 holds 7, 8, 9. matrix[1][2], row 1 and column 2, is 6. matrix.length is 3, the number of rows, and matrix[0].length is 3, the number of columns. col 0 col 1 col 2 row 0 1 99 3 row 1 4 5 6 row 2 7 8 9 matrix[1][2] is 6 matrix.length = 3 (rows) len(matrix) = 3 (rows) matrix[0].length = 3 (columns) len(matrix[0]) = 3 (columns)

Worked Examples

Example 1: Print a Grid

The fundamental pattern - nested loops to visit every element.

int[][] matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

// Outer loop: each row
for (int row = 0; row < matrix.length; row++) {
    // Inner loop: each column in this row
    for (int col = 0; col < matrix[row].length; col++) {
        System.out.print(matrix[row][col] + "\t");
    }
    System.out.println();  // new line after each row
}
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# Outer loop: each row
for row in range(len(matrix)):
    # Inner loop: each column in this row
    for col in range(len(matrix[row])):
        print(matrix[row][col], end="\t")   # end="\t" adds a tab, stays on the line
    print()   # new line after each row

Output:

1	2	3
4	5	6
7	8	9

The outer loop iterates over rows. For each row, the inner loop iterates over columns. \t adds a tab between values for neat alignment.


Example 2: Row Sum

Calculate the sum of a single row.

int[][] grades = {
    {85, 92, 78},
    {90, 88, 95},
    {70, 65, 80}
};

int targetRow = 1;
int sum = 0;

for (int col = 0; col < grades[targetRow].length; col++) {
    sum = sum + grades[targetRow][col];
}

System.out.println("Row " + targetRow + " sum: " + sum);  // Row 1 sum: 273
grades = [
    [85, 92, 78],
    [90, 88, 95],
    [70, 65, 80]
]

target_row = 1
total = 0   # sum is a built-in function name in Python, so we call it total

for col in range(len(grades[target_row])):
    total = total + grades[target_row][col]

print("Row " + str(target_row) + " sum: " + str(total))  # Row 1 sum: 273

Notice: only one loop is needed because we fix the row and iterate over columns.


Example 3: Search in a 2D Array

Find whether a target value exists anywhere in the grid.

int[][] data = {
    {12, 45, 67},
    {89, 23, 56},
    {34, 78, 90}
};

int target = 23;
boolean found = false;

for (int row = 0; row < data.length && !found; row++) {
    for (int col = 0; col < data[row].length && !found; col++) {
        if (data[row][col] == target) {
            found = true;
            System.out.println("Found " + target + " at [" + row + "][" + col + "]");
        }
    }
}

if (!found) {
    System.out.println(target + " not found.");
}
data = [
    [12, 45, 67],
    [89, 23, 56],
    [34, 78, 90]
]

target = 23
found = False

# while loops keep the early-exit check in the loop condition (no break needed)
row = 0
while row < len(data) and found == False:
    col = 0
    while col < len(data[row]) and found == False:
        if data[row][col] == target:
            found = True
            print("Found " + str(target) + " at [" + str(row) + "][" + str(col) + "]")
        col = col + 1
    row = row + 1

if found == False:
    print(str(target) + " not found.")

Output: Found 23 at [1][1]

The && !found condition provides an early exit - no point continuing once the value is found.


Example 4: Transpose

Swapping rows and columns into a new array.

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

// Transpose: rows become columns and columns become rows
int[][] transposed = new int[original[0].length][original.length];

for (int row = 0; row < original.length; row++) {
    for (int col = 0; col < original[row].length; col++) {
        transposed[col][row] = original[row][col];
    }
}

// Print transposed (3 rows, 2 cols)
for (int row = 0; row < transposed.length; row++) {
    for (int col = 0; col < transposed[row].length; col++) {
        System.out.print(transposed[row][col] + "\t");
    }
    System.out.println();
}
original = [
    [1, 2, 3],
    [4, 5, 6]
]

# Transpose: rows become columns and columns become rows.
# Python lists grow dynamically - this pre-built grid of zeros just
# mirrors Java's new int[3][2] so we can write into each slot:
transposed = [
    [0, 0],
    [0, 0],
    [0, 0]
]

for row in range(len(original)):
    for col in range(len(original[row])):
        transposed[col][row] = original[row][col]

# Print transposed (3 rows, 2 cols)
for row in range(len(transposed)):
    for col in range(len(transposed[row])):
        print(transposed[row][col], end="\t")
    print()

Output:

1	4
2	5
3	6

The key line is transposed[col][row] = original[row][col] - each element’s row and column indices are swapped.


Quick Check

Q1. Given int[][] matrix = new int[3][4], what does matrix.length return?

Q2. Given int[][] matrix = new int[3][4], which access is valid?

Q3. What does this code print?

int[][] m = { {1,2,3}, {4,5,6}, {7,8,9} };
for (int r = 0; r < m.length; r++) {
    for (int c = 0; c < m[r].length; c++) {
        System.out.print(m[r][c] + " ");
    }
    System.out.println();
}
m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for r in range(len(m)):
    for c in range(len(m[r])):
        print(m[r][c], end=" ")
    print()

Q4. Which of these is a common error when accessing 2D arrays?

Q5. Given int[][] matrix = new int[5][3], what is matrix[0].length?


Trace Exercise

Trace this nested loop over a 3x3 matrix. Fill in the value of matrix[row][col] and the running sum at each step.

int[][] matrix = {
    {2, 4, 6},
    {1, 3, 5},
    {8, 7, 9}
};

int sum = 0;
for (int row = 0; row < matrix.length; row++) {
    for (int col = 0; col < matrix[row].length; col++) {
        sum = sum + matrix[row][col];
    }
}
System.out.println("Total: " + sum);
matrix = [
    [2, 4, 6],
    [1, 3, 5],
    [8, 7, 9]
]

total = 0   # sum is a built-in function name in Python, so we call it total
for row in range(len(matrix)):
    for col in range(len(matrix[row])):
        total = total + matrix[row][col]
print("Total:", total)
rowcolmatrix[row][col]sum
00
01
02
10
11
12
20
21
22

Final output: Total:


Code Completion

Complete the code that calculates the sum of a specific column in a 2D array.

Unlike a row sum (which fixes the row and loops over columns), a column sum fixes the column and loops over each row. Fill in the blanks to complete the column sum calculation:

int[][] grades = {
    {85, 92, 78},
    {90, 88, 95},
    {70, 65, 80}
};

int targetCol = 1;
int sum = 0;

for (int row = 0; row < ; row++) {
    sum = sum + ;
}

System.out.println("Column " + targetCol + " sum: " + );

Spot the Error

This code is supposed to sum all elements of a 2D array using nested loops, but it crashes with an ArrayIndexOutOfBoundsException. The bug is a classic off-by-one error in the loop boundary. Select the buggy line, then pick the fix.

1int[][] matrix = { {1,2}, {3,4}, {5,6} }; 2 3int sum = 0; 4for (int row = 0; row <= matrix.length; row++) { 5 for (int col = 0; col < matrix[row].length; col++) { 6 sum = sum + matrix[row][col]; 7 } 8} 9System.out.println("Sum: " + sum);

Pick the correct fix:


Predict the Output

This code uses nested loops to traverse a 2D array row by row, printing each element followed by a space and starting a new line after each row. What is the exact output of this code?

int[][] arr = { {10, 20, 30}, {40, 50, 60} };
for (int r = 0; r < arr.length; r++) {
    for (int c = 0; c < arr[r].length; c++) {
        System.out.print(arr[r][c] + " ");
    }
    System.out.println();
}

Type your answer (use \n to indicate a new line):

Pay close attention to spaces and newlines in output prediction questions. The print method does not add a newline, while println does.


Practice Exercises

Core

  1. Multiplication Table - Write code in main that creates a 5x5 int[][] where table[r][c] = (r+1) * (c+1). Print the result as a formatted grid.

  2. Find the Largest - Given int[][] data = { {3,7,2}, {9,1,5}, {4,8,6} }, write code to find and print the largest value and its position [row][col].

  3. Row Averages - Given a 2D array of student grades (rows = students, columns = assignments), calculate and print each student’s average grade.

Extension

  1. Transpose - Write code that transposes a 2x4 array into a 4x2 array. Print both the original and transposed arrays.

  2. Matrix Addition - Given two 3x3 arrays a and b, create a new array result where result[r][c] = a[r][c] + b[r][c]. Print all three matrices.

Challenge

  1. Tic-Tac-Toe Board - Create a char[3][3] array representing a tic-tac-toe board. Write code that:
    • Initialises all cells to '-'
    • Places some 'X' and 'O' values
    • Prints the board with | separators between columns
    • Checks whether a given row contains three of the same non-empty character (a win)

GitHub Classroom

2D Arrays Practice
Practice nested loops with a grade table: print the grid, calculate row totals, column averages, find the highest grade, and search for a value. Includes a Practice Rooms challenge: build a weekly table from the sign-up sheet for three music practice rooms, then check it against each room's daily limit.

A class assignment on GitHub Classroom: use it when your teacher has set it. It needs a free GitHub account.

Working in the Codespace

  1. Accept and open. Accept the assignment above, open the link in the email from GitHub, then press Open in Codespace. In Java, change the status bar from Lightweight to Standard mode.
  2. Write and check. Open src/TwoDArrays.java and complete each TODO using nested for loops. Press Run and compare the output with the comments, or run bash run-tests.sh in the Terminal.
  3. Submit. In Source Control, write a message, press Commit, then Sync Changes. Your teacher’s feedback arrives as a pull request called Feedback.

There is also a challenge file src/PracticeRooms.java - this is optional and harder.

The full Codespace guide, with pictures


Connections