A two-dimensional array is often imagined as a perfect table where every row has the same number of columns. Java, however, gives you more flexibility. A jagged array is a multidimensional array in which different rows can have different lengths.
What Is a Jagged Array?
A jagged array is an array of arrays where each inner array can contain a different number of elements. This makes it useful when each row naturally contains a different amount of data.
int[][] numbers = {
{10, 20},
{30, 40, 50},
{60, 70, 80, 90}
};
Here, the first row contains two elements, the second contains three, and the third contains four. Unlike a traditional rectangular matrix, the rows do not need to have equal lengths.
| Row | Number of Elements | Values |
|---|---|---|
| 0 | 2 | 10, 20 |
| 1 | 3 | 30, 40, 50 |
| 2 | 4 | 60, 70, 80, 90 |
Why Does Java Support Jagged Arrays?
Not every real-world dataset fits neatly into a rectangle. Consider a school where different classes offer different numbers of subjects. Forcing every class to have the same number of subject positions would waste space or make the data model unnecessarily complicated.
A jagged array allows each row to contain exactly the number of elements it needs. This makes the structure flexible while still using Java's array mechanism.
Declaring a Jagged Array
The declaration looks similar to an ordinary two-dimensional array.
int[][] numbers;
At this point, only the array reference has been declared. The individual rows can be created with different lengths later.
Creating a Jagged Array
To create a jagged array, first specify the number of rows. Then create each row separately with the required length.
int[][] numbers = new int[3][]; numbers[0] = new int[2]; numbers[1] = new int[3]; numbers[2] = new int[4];
The first dimension creates three row references. The second dimension is intentionally left unspecified, allowing every row to have its own length.
Important: In new int[3][], Java creates space for three row references, but the individual row arrays are not created until you assign them.
Initializing a Jagged Array Directly
When the values are already known, the simplest approach is to initialize the rows directly.
int[][] numbers = {
{1, 2},
{3, 4, 5},
{6, 7, 8, 9}
};
Java automatically creates three inner arrays with lengths 2, 3, and 4 respectively.
Accessing Elements
Accessing an element of a jagged array uses the same row-and-column syntax used with two-dimensional arrays.
int[][] numbers = {
{10, 20},
{30, 40, 50},
{60, 70, 80, 90}
};
System.out.println(numbers[0][1]);
System.out.println(numbers[2][3]);
The first statement accesses 20 from row 0, column 1. The second accesses 90 from row 2, column 3.
Remember: In a jagged array, the valid column indexes depend on the specific row. You cannot assume every row has the same number of columns.
Finding the Length of Each Row
The length property of the outer array tells you how many rows exist. The length property of an individual row tells you how many elements that row contains.
int[][] numbers = {
{10, 20},
{30, 40, 50},
{60, 70, 80, 90}
};
System.out.println(numbers.length);
System.out.println(numbers[0].length);
System.out.println(numbers[1].length);
System.out.println(numbers[2].length);
The output is 3, 2, 3, and 4. There are three rows, and each row has its own length.
Traversing a Jagged Array
A nested loop is commonly used to traverse a jagged array. The important difference is that the inner loop must use the length of the current row.
int[][] numbers = { {10, 20}, {30, 40, 50}, {60, 70, 80, 90} }; for (int i = 0; i < numbers.length; i++) { for (int j = 0; j < numbers[i].length; j++) { System.out.print(numbers[i][j] + " "); } System.out.println(); }
The expression numbers[i].length is important because each row may have a different number of elements.
Traversing with for-each
A nested enhanced for loop is often the cleanest way to read every value from a jagged array.
int[][] numbers = { {10, 20}, {30, 40, 50}, {60, 70, 80, 90} }; for (int[] row : numbers) { for (int value : row) { System.out.print(value + " "); } System.out.println(); }
The outer loop retrieves each row as an integer array, and the inner loop processes the elements within that row.
Practical Example: Different Subjects Per Student
Suppose students are enrolled in different numbers of subjects. A jagged array can represent their marks without adding unnecessary empty positions.
int[][] marks = {
{85, 90, 78},
{92, 88},
{76, 84, 89, 91}
};
The first student has three marks, the second has two, and the third has four. Each row stores only the data relevant to that student.
Calculating Row Totals
Jagged arrays are particularly useful when each row represents an independent collection. For example, you can calculate the total for every row separately.
int[][] marks = { {85, 90, 78}, {92, 88}, {76, 84, 89, 91} }; for (int i = 0; i < marks.length; i++) { int total = 0; for (int j = 0; j < marks[i].length; j++) { total += marks[i][j]; } System.out.println("Total = " + total); }
Each row is processed independently, so its total is calculated according to the number of elements that row actually contains.
Jagged Array with Empty Rows
A jagged array can contain rows of different lengths, including a row with zero elements.
int[][] numbers = new int[3][]; numbers[0] = new int[2]; numbers[1] = new int[0]; numbers[2] = new int[3];
The second row exists, but it contains no elements. Its length is 0.
Jagged Array and null Rows
There is another important detail when creating jagged arrays. If you create the outer array but do not initialize a particular row, that row reference remains null.
int[][] numbers = new int[3][]; numbers[0] = new int[2]; System.out.println(numbers[1]);
Here, numbers[1] is null because no inner array has been assigned to that position yet.
Warning: Trying to access numbers[1].length before initializing that row causes a NullPointerException.
Jagged Arrays vs Rectangular Arrays
| Feature | Rectangular Array | Jagged Array |
|---|---|---|
| Row lengths | Usually equal | Can differ |
| Creation | new int[3][4] | new int[3][] |
| Memory structure | Rows have consistent sizes | Each row can have its own size |
| Best for | Uniform tables and matrices | Variable-sized groups |
| Traversal | Nested loops | Nested loops using each row's length |
Common Beginner Mistakes
- Assuming every row has the same length.
- Using a fixed column count while traversing rows of different sizes.
- Accessing a row before initializing it.
- Confusing an empty row with a null row.
- Using the outer array's length as the length of every inner array.
Interview Insight
A common interview question is: “What is a jagged array in Java?” A strong answer is: “A jagged array is a multidimensional array where the inner arrays can have different lengths. In Java, this is possible because a two-dimensional array is actually an array of array references.”
| Concept | Key Point |
|---|---|
| Jagged array | Rows can have different lengths |
| Outer length | Number of row references |
| Row length | Number of elements in that specific row |
| Uninitialized row | Contains null |
| Empty row | Exists but has length 0 |
| Traversal | Use each row's own length |
Jagged arrays demonstrate one of Java's most useful array design features: multidimensional arrays do not have to be perfectly rectangular. When different groups naturally contain different amounts of data, a jagged structure can represent that data directly and avoid unnecessary positions.
