Java Multidimensional Arrays — 2D Arrays, Jagged Arrays & More

3 minute read

A multidimensional array is an array of arrays. The most common is the 2D array — perfect for representing tables, grids, matrices, and game boards.


Declaring and Creating 2D Arrays

// Declare and create a 3×4 matrix (3 rows, 4 columns)
int[][] matrix = new int[3][4];

This creates a grid with 3 rows and 4 columns, all initialised to 0.

Initialise with Values

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

Access Elements

System.out.println(grid[0][0]);  // 1  (row 0, col 0)
System.out.println(grid[1][2]);  // 6  (row 1, col 2)
System.out.println(grid[2][1]);  // 8  (row 2, col 1)

Dimensions

int rows = grid.length;       // 3
int cols = grid[0].length;    // 3

Iterating Over a 2D Array

Nested for Loops

for (int i = 0; i < grid.length; i++) {
    for (int j = 0; j < grid[i].length; j++) {
        System.out.printf("%3d", grid[i][j]);
    }
    System.out.println();
}

Output:

  1  2  3
  4  5  6
  7  8  9

Enhanced for-each

for (int[] row : grid) {
    for (int val : row) {
        System.out.printf("%3d", val);
    }
    System.out.println();
}

Jagged Arrays (Ragged Arrays)

In Java, each row can have a different number of columns:

int[][] jagged = new int[3][];
jagged[0] = new int[]{1, 2};
jagged[1] = new int[]{3, 4, 5, 6};
jagged[2] = new int[]{7};
Row 0: [1, 2]
Row 1: [3, 4, 5, 6]
Row 2: [7]

Always use jagged[i].length — not a fixed column count — when iterating:

for (int i = 0; i < jagged.length; i++) {
    for (int j = 0; j < jagged[i].length; j++) {
        System.out.print(jagged[i][j] + " ");
    }
    System.out.println();
}

Memory Layout

A 2D array in Java is not a single contiguous block (unlike C). It is an array of references to row arrays:

matrix ──→ [ ref0, ref1, ref2 ]
              │      │      │
              ▼      ▼      ▼
           [1,2,3] [4,5,6] [7,8,9]

Each row is a separate object on the heap, which is why jagged arrays are possible.


Practical Example 1 — Matrix Addition

public static int[][] add(int[][] a, int[][] b) {
    int rows = a.length;
    int cols = a[0].length;
    int[][] result = new int[rows][cols];

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            result[i][j] = a[i][j] + b[i][j];
        }
    }
    return result;
}

Practical Example 2 — Matrix Transpose

public static int[][] transpose(int[][] matrix) {
    int rows = matrix.length;
    int cols = matrix[0].length;
    int[][] result = new int[cols][rows];

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            result[j][i] = matrix[i][j];
        }
    }
    return result;
}

Practical Example 3 — Tic-Tac-Toe Board

public class TicTacToe {
    private char[][] board = {
        {' ', ' ', ' '},
        {' ', ' ', ' '},
        {' ', ' ', ' '}
    };

    public void place(int row, int col, char symbol) {
        if (board[row][col] != ' ') {
            throw new IllegalStateException("Cell already taken");
        }
        board[row][col] = symbol;
    }

    public void print() {
        for (int i = 0; i < 3; i++) {
            System.out.printf(" %c | %c | %c %n",
                board[i][0], board[i][1], board[i][2]);
            if (i < 2) System.out.println("---+---+---");
        }
    }
}

Practical Example 4 — Student Grade Matrix

String[] students = {"Alice", "Bob", "Charlie"};
int[][] grades = {
    {90, 85, 92},   // Alice: Math, Science, English
    {78, 88, 95},   // Bob
    {85, 90, 80}    // Charlie
};

for (int i = 0; i < students.length; i++) {
    int sum = 0;
    for (int g : grades[i]) sum += g;
    double avg = (double) sum / grades[i].length;
    System.out.printf("%s → Average: %.1f%n", students[i], avg);
}

3D Arrays and Beyond

int[][][] cube = new int[3][3][3];
cube[0][1][2] = 42;

3D arrays are rare in practice. If you find yourself using them, consider whether a List<List<List<T>>> or a custom class would be clearer.


Common Mistakes

Mistake Problem Fix
Using matrix.length for columns Gives row count Use matrix[0].length
Assuming rectangular shape Jagged arrays break this Check each row.length
Off-by-one in nested loops ArrayIndexOutOfBoundsException Use < length, not <=
Printing with toString() Shows references, not values Use Arrays.deepToString()

Key Takeaways

  1. A 2D array is an array of arrays — each row is a separate object on the heap.
  2. Jagged arrays allow rows of different lengths.
  3. Use nested loops or for-each to traverse.
  4. Use Arrays.deepToString() and Arrays.deepEquals() for printing and comparing.
  5. For most real-world work, prefer List<List<T>> unless performance demands arrays.

What’s Next?

We leave arrays behind and dive into Strings — Java’s most used class. You’ll learn about immutability, the String pool, and the critical difference between == and .equals().

Updated: