1. Jagged arrays differ from two-dimensional arrays
We’ve reached the topic many call “jagged arrays” — in English, jagged arrays. Unlike two-dimensional arrays, jagged arrays let you store rows of different lengths. It’s like having a complex of buildings where each building has its own number of apartments — one building has 5 apartments, another 20, and the third only one.
A jagged array is an array whose every element is an array, and the nested arrays (also called “subarrays”) can have different lengths.
Key difference:
- In a two-dimensional array, each “row” (and each “column”) has the same number of elements. Example: int[][] grid = new int[3][5]; — we always have 3 rows of 5 elements.
- In a jagged array, each row can have a different length! Example: int[][] jagged = new int[3][]; — and only then do we initialize each row (subarray) individually.
Here’s what it looks like visually:
Two-dimensional array (3x3):
┌───┬───┬───┐
│ 1 │ 2 │ 3 │
├───┼───┼───┤
│ 4 │ 5 │ 6 │
├───┼───┼───┤
│ 7 │ 8 │ 9 │
└───┴───┴───┘
Jagged array (different lengths):
┌───┬───┐
│ 1 │ 2 │
├───┼───┼───┬───┐
│ 3 │ 4 │ 5 │ 6 │
├───┼───┴───┴───┘
│ 7 │
└───┘
2. Syntax for declaring and initializing a jagged array
Declaring a jagged array is no scarier than previous types! Don’t be afraid of the double square brackets:
int[][] jaggedArray = new int[3][];
This means we have an array of 3 elements, and each of them is also an array of int. But the inner arrays are not created yet! To make this clearer, let’s break it down.
Step-by-step initialization of a jagged array
Step 1 — create the main (outer) array:
int[][] jaggedArray = new int[3][];
Now we have 3 “rows”, but all of them are currently null.
Step 2 — create and size the inner arrays (subarrays):
For example, let the first row be length 2, the second — 4, the third — 3:
jaggedArray[0] = new int[2]; // 2 elements in the first row
jaggedArray[1] = new int[4]; // 4 elements in the second row
jaggedArray[2] = new int[3]; // 3 elements in the third row
Step 3 — fill with values:
The inner arrays are ordinary arrays! For example:
jaggedArray[0][0] = 1;
jaggedArray[0][1] = 2;
jaggedArray[1][0] = 3;
jaggedArray[1][1] = 4;
jaggedArray[1][2] = 5;
jaggedArray[1][3] = 6;
jaggedArray[2][0] = 7;
jaggedArray[2][1] = 8;
jaggedArray[2][2] = 9;
Concise initialization of a jagged array
You can create and populate a jagged array at once if you know the values in advance:
int[][] jaggedArray = new int[][]
{
new int[] { 1, 2 },
new int[] { 3, 4, 5, 6 },
new int[] { 7, 8, 9 }
};
Or a bit shorter, omitting the inner array types:
int[][] jaggedArray =
{
{ 1, 2 },
{ 3, 4, 5, 6 },
{ 7, 8, 9 }
};
3. Iterating over and working with jagged arrays
Iterating a jagged array is no harder than a two-dimensional one, but now the outer loop goes over rows and the inner one over the elements of a row (which may have different lengths):
for (int i = 0; i < jaggedArray.length; i++)
{
System.out.println("Row " + i + ":");
for (int j = 0; j < jaggedArray[i].length; j++)
{
System.out.print(jaggedArray[i][j] + " ");
}
System.out.println();
}
Output on screen:
Row 0:
1 2
Row 1:
3 4 5 6
Row 2:
7 8 9
You can use for-each so you don’t have to think about indices:
for (int[] row : jaggedArray)
{
for (int value : row)
{
System.out.print(value + " ");
}
System.out.println();
}
4. Typical use cases for jagged arrays
When can a jagged array be more useful than a two-dimensional one?
- If you store a different number of items per user: grades by subject, purchases, comments, and so on.
- If your data has a triangular or step-like structure (for example, printing pyramids, Pascal’s triangle, etc.).
- If you want to save memory: in a two-dimensional array all rows are fixed, whereas in a jagged array you allocate only as many elements as needed.
Real-world example: a student grade manager
Suppose we have three students, and here are their grades for different math assignments:
| Student | Grades |
|---|---|
| 0 | 5, 4 |
| 1 | 3, 4, 4 |
| 2 | 5 |
Let’s declare such an array:
int[][] studentMarks = new int[3][];
studentMarks[0] = new int[] { 5, 4 }; // First student — 2 grades
studentMarks[1] = new int[] { 3, 4, 4 }; // Second student — 3 grades
studentMarks[2] = new int[] { 5 }; // Third student — 1 grade
Print each student’s grades:
for (int i = 0; i < studentMarks.length; i++)
{
System.out.print("Student " + i + ": ");
for (int j = 0; j < studentMarks[i].length; j++)
{
System.out.print(studentMarks[i][j] + " ");
}
System.out.println();
}
Using jagged arrays with other types
An array of anything can be jagged: strings, arrays of other arrays (deeper!), even your own objects.
Example: an array of strings
String[][] groups = {
{ "Ivan", "Pyotr" },
{ "Maria", "Alexey", "Sergey" },
{ "Vasilisa" }
};
5. Three-dimensional and multidimensional arrays
And here’s another interesting fact about arrays that you’ve probably guessed already. If you can make a two-dimensional array, can you make a three-dimensional one?
Yes, you can create arrays of any dimensionality. Such arrays are called multidimensional.
How to declare multidimensional arrays
Just list the required number of dimensions in brackets:
int[][][] cube = new int[2][3][4]; // 2 "layers", 3 rows, 4 columns
cube[0][1][2] = 99;
Here we have a three-dimensional array:
- 2 elements along the first coordinate,
- 3 — along the second,
- 4 — along the third.
Such an array is one big “cube” of data laid out consecutively.
Iterating over a three-dimensional array
Access to an element is performed with all indices at once:
for (int i = 0; i < cube.length; i++)
{
for (int j = 0; j < cube[i].length; j++)
{
for (int k = 0; k < cube[i][j].length; k++)
{
System.out.print(cube[i][j][k] + " ");
}
System.out.println();
}
System.out.println("---");
}
- Indices are zero-based, as always in Java.
- There will be 2 × 3 × 4 = 24 elements in such an array.
Practical examples of multidimensional arrays
- 2D — tables, chessboards, images.
- 3D — “cubes” in computer graphics, data for scientific computations (for example, temperature at different points in space and time).
- 4D and higher — rarely used, but found in advanced mathematics, simulations, machine learning, etc.
6. Common mistakes when working with multidimensional arrays
Error No. 1: Out-of-bounds access
The most common error is trying to access a non-existent element, for example:
int[][] arr = new int[2][3];
arr[2][0] = 5; // Error! No row with index 2 (there are only 0 and 1)
arr[0][3] = 7; // Error! No column with index 3 (there are only 0, 1, 2)
With such access, the program will throw ArrayIndexOutOfBoundsException. Always check that indices are within valid bounds: from 0 to length - 1.
Error No. 2: Uninitialized rows in a jagged array
If you create a jagged array and forget to initialize the inner arrays, attempting to access them will result in a NullPointerException:
int[][] jagged = new int[3][];
jagged[0][0] = 5; // Error! jagged[0] == null
First you need to create the inner array: jagged[0] = new int[2];
Error No. 3: Incorrect use of array length
People mix up matrix.length (number of rows) and matrix[0].length (number of columns). This happens especially often when copying, iterating, or summing by columns.
Error No. 4: Assuming all rows have the same length
In jagged arrays rows can have different lengths! If you write matrix[i][j], make sure that j < matrix[i].length.
Error No. 5: Mixing up index order
Sometimes people forget that row comes first and then column: matrix[row][column]. Not the other way around!
GO TO FULL VERSION