Skip to content
Java arrays 5 min read

Jagged Arrays

A jagged array (also called a ragged array) is an array of arrays where each inner array can have a different length. Unlike a true rectangular 2D array, the rows in a jagged array don’t have to line up in columns — they can each be as long or as short as you need.

Why Use Jagged Arrays?

A regular multidimensional array allocates a perfect rectangle of memory — every row has the same number of columns. That’s fine when your data really is rectangular, but it wastes memory when rows naturally vary in size.

Imagine storing a triangle of numbers, or a monthly calendar where February has fewer days than July. A jagged array is the right tool for those jobs.

SituationBest choice
All rows same lengthint[3][4] rectangular array
Rows have different lengthsJagged array
Sparse or triangular dataJagged array

Declaring and Creating a Jagged Array

You create a jagged array by specifying only the number of rows upfront, then allocating each row separately.

// Declare an array with 3 rows — lengths unspecified yet
int[][] triangle = new int[3][];

// Allocate each row individually
triangle[0] = new int[1];
triangle[1] = new int[2];
triangle[2] = new int[3];

After this code, triangle[0] has 1 element, triangle[1] has 2, and triangle[2] has 3.

Initializing with Values

You can combine declaration and initialization using an array initializer:

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

This gives you a 4-row jagged array where row lengths grow from 1 to 4.

Accessing Elements

Access works the same way as any 2D array — array[row][column]. The difference is that valid column indices vary by row.

int[][] jagged = {
    {10},
    {20, 30},
    {40, 50, 60}
};

System.out.println(jagged[0][0]); // 10
System.out.println(jagged[1][1]); // 30
System.out.println(jagged[2][2]); // 60

Output:

10
30
60

Warning: Accessing jagged[0][1] above would throw an ArrayIndexOutOfBoundsException because row 0 only has one element. Always check the row length before indexing.

Iterating Over a Jagged Array

Use a nested loop, but read each row’s length dynamically using .length:

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

for (int row = 0; row < data.length; row++) {
    for (int col = 0; col < data[row].length; col++) {
        System.out.print(data[row][col] + " ");
    }
    System.out.println();
}

Output:

1 
2 3 
4 5 6 

You can also use a for-each loop since each inner array is just a regular int[]:

for (int[] row : data) {
    for (int val : row) {
        System.out.print(val + " ");
    }
    System.out.println();
}

The output is identical. The for-each version is cleaner when you don’t need the index.

Practical Example: Pascal’s Triangle

Pascal’s Triangle is a classic use case for jagged arrays — row n has exactly n + 1 elements.

public class PascalTriangle {
    public static void main(String[] args) {
        int rows = 5;
        int[][] pascal = new int[rows][];

        for (int i = 0; i < rows; i++) {
            pascal[i] = new int[i + 1];
            pascal[i][0] = 1;
            pascal[i][i] = 1;
            for (int j = 1; j < i; j++) {
                pascal[i][j] = pascal[i - 1][j - 1] + pascal[i - 1][j];
            }
        }

        for (int[] row : pascal) {
            for (int val : row) {
                System.out.print(val + " ");
            }
            System.out.println();
        }
    }
}

Output:

1 
1 1 
1 2 1 
1 3 3 1 
1 4 6 4 1 

A rectangular int[5][5] would allocate 25 cells; the jagged version allocates exactly 15 — the only cells that actually hold data.

Checking Row Lengths

You can inspect lengths at any time using .length:

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

System.out.println("Number of rows: " + jagged.length);
for (int i = 0; i < jagged.length; i++) {
    System.out.println("Row " + i + " length: " + jagged[i].length);
}

Output:

Number of rows: 3
Row 0 length: 3
Row 1 length: 2
Row 2 length: 1

See Array length for a full explanation of the .length property.

Jagged vs Rectangular 2D Arrays

// Rectangular — every row has exactly 4 columns (12 cells total)
int[][] rect = new int[3][4];

// Jagged — rows have 1, 2, and 3 columns (6 cells total)
int[][] jagged = new int[3][];
jagged[0] = new int[1];
jagged[1] = new int[2];
jagged[2] = new int[3];
FeatureRectangularJagged
Row lengthsAll equalCan vary
MemoryMay waste spaceAllocates exactly what’s needed
Access syntaxa[row][col]a[row][col] (same)
IterationSimple nested loopNested loop using a[row].length
Use caseMatrix math, gridsTriangles, calendars, graphs

Tip: When every row really does have the same number of columns, use a rectangular array — it’s simpler and the JVM can optimize sequential access more predictably.

Under the Hood

In Java, a 2D array is always an array of references to arrays — there is no native “matrix” type in the JVM. When you write int[][] rect = new int[3][4], the JVM creates:

  1. One int[][] object on the heap holding 3 references.
  2. Three separate int[4] objects, each on the heap.

A jagged array is identical in structure — you’re just making each inner int[] a different size. The outer array still holds a reference to each row, regardless of how long that row is.

This also means:

  • Each row is an independent object. You can reassign jagged[1] = new int[10] at any time.
  • Row objects are not necessarily laid out next to each other in memory. For large matrices with many small rows, this can hurt cache performance compared to a single flat int[] of size rows * cols.
  • jagged[i] is simply a reference (null until you assign a row), so accessing an uninitialized row will throw a NullPointerException.
int[][] bad = new int[3][];
// bad[0] is null here — we never assigned a row
System.out.println(bad[0].length); // NullPointerException!

Warning: Always initialize every row before accessing it. A null row looks valid from the compiler’s perspective but explodes at runtime.

For performance-critical numeric code (image processing, scientific computing), consider a flat int[] with manual index arithmetic (array[row * cols + col]) so all data is contiguous in memory. For most application code, jagged arrays are perfectly efficient.

  • Multidimensional Arrays — rectangular 2D and higher-dimension arrays in Java
  • Arrays — the foundation: declaration, indexing, and traversal
  • Array length — how the .length property works for both flat and nested arrays
  • for-each Loop — the cleanest way to iterate rows in a jagged array
  • Arrays Utility Class — sorting, filling, copying, and comparing arrays with java.util.Arrays
  • Array of Objects — applying the same jagged pattern with object references instead of primitives
Last updated June 13, 2026
Was this helpful?