What is a jagged (ragged) array in Java, and how do you create one with rows of differing length?
answer
- jagged = rows of differing length
- new int[3][] -> outer only, rows are null
- new int[3][4] -> all rows allocated to 0
- loop with a[i].length, not a fixed width
- cannot skip an earlier dimension: new int[][4] illegal
basics
~10 sA jagged array is a 2D array whose rows have different lengths. Because Java's 2D arrays are arrays of arrays, you just create the outer array first, then assign each row its own length.
solid answer
~40 sA jagged (ragged) array is an array of arrays where the inner arrays have differing lengths — a triangle, for example. Java supports this naturally because int[][] is an array of int[] references, not a rectangle. You create one by leaving the inner dimension unspecified: new int[3][] allocates only the outer array of three null references, then you assign each row separately, e.g. a[0] = new int[1]; a[1] = new int[2]; a[2] = new int[3];. You can also use an array initializer like {{1},{2,3},{4,5,6}}. The key gotcha: with new int[3][], every row starts as null, so a[i].length or a[i][j] throws NullPointerException until you allocate that row. Each row's length is independent (a[i].length), and there's no single column count. Jagged arrays save memory for triangular or variable-width data and are common in adjacency-list-style structures.
code
java · 15 lines// Build a jagged "triangle": row i has i+1 elements
int n = 3;
int[][] tri = new int[n][]; // outer array; all rows are null
for (int i = 0; i < n; i++) {
tri[i] = new int[i + 1]; // allocate this row
for (int j = 0; j < tri[i].length; j++) {
tri[i][j] = i + j;
}
}
// Equivalent literal:
int[][] same = { {0}, {1, 2}, {2, 3, 4} };
// NPE trap:
int[][] bad = new int[3][]; // rows are null
// int x = bad[0][0]; // NullPointerException — row 0 not allocatedgo deeper
Can recognize a jagged array and create one with an initializer like {{1},{2,3}}.
Creates jagged arrays via new int[n][] plus per-row allocation, knows rows start null, and iterates using a[i].length.
Explains memory savings for triangular data, the NPE/AIOOBE traps, and chooses jagged vs. flattened representations appropriately.
Advises on data-structure modeling (adjacency lists, sparse/triangular matrices), API contracts around nullable rows, and when ragged layouts are worth their indirection cost.
## Definition A **jagged array** (also *ragged array*) is a multidimensional array in which the sub-arrays (rows) are **not all the same length**. Example shape: ``` row 0: [_] length 1 row 1: [_][_] length 2 row 2: [_][_][_] length 3 ``` This is impossible to express directly in a language with true rectangular arrays, but it is the *natural* case in Java. ## Why Java makes it easy As covered in the array-of-arrays concept: `int[][]` is an **array of `int[]` references**. The outer array just holds references; nothing constrains the referenced inner arrays to be the same size. So a jagged array is not a special feature — it's what you get when you allocate the rows independently. ## How to create one ### 1. Partial allocation (most explicit) Specify only the outer dimension; leave inner empty: ```java int[][] a = new int[3][]; // outer array of 3 nulls; NO inner arrays yet a[0] = new int[1]; a[1] = new int[2]; a[2] = new int[3]; ``` After `new int[3][]`, `a.length` is 3 but every `a[i]` is **null**. You must allocate each row before using it. ### 2. Array initializer (literal) ```java int[][] a = { {1}, {2, 3}, {4, 5, 6} }; ``` The compiler infers each row's length from the braces. This is concise for known data. ### 3. In a loop (computed lengths) ```java int[][] tri = new int[n][]; for (int i = 0; i < n; i++) { tri[i] = new int[i + 1]; // row i has i+1 elements } ``` ## The null gotcha The most common bug: `new int[3][]` gives you `[null, null, null]`. Touching `a[0].length` or `a[0][0]` before assigning `a[0] = new int[...]` throws **`NullPointerException`**, because you are dereferencing a null reference. Contrast `new int[3][4]`, which allocates all rows and fills them with the default value (`0`), so no NPE. ## Querying lengths There is **no column count** for a jagged array. You query each row: `a.length` for the number of rows and `a[i].length` for the length of row i. Iteration must therefore use the *inner* length each time: ```java for (int i = 0; i < a.length; i++) for (int j = 0; j < a[i].length; j++) // a[i].length, not a fixed width use(a[i][j]); ``` Using a single fixed width across all rows is a classic source of `ArrayIndexOutOfBoundsException`. ## Why use jagged arrays - **Memory** — a triangular matrix stored jagged uses ~half the cells of a full square. - **Natural fit** — adjacency lists (each node has a different number of neighbors), variable-length records, Pascal's triangle, etc. - **Default values** — once a row is allocated, its elements are at the type default (`0`, `null`, `false`). ## Higher dimensions You can leave any *trailing* dimensions empty: `new int[3][][]` is legal (outer allocated, the rest null), but `new int[][4]` is **not** — you cannot specify a later dimension while skipping an earlier one.
- What happens if you call a[0].length right after int[][] a = new int[3][]?It throws NullPointerException: new int[3][] only allocates the outer array, so a[0] is null and you are dereferencing null.
- Is new int[][4] valid Java?No. You may leave trailing dimensions unspecified (new int[3][]) but cannot specify a later dimension while skipping an earlier one.
saying these in an interview costs you the question
- Assuming new int[3][] allocates the inner rows (it leaves them null)
- Iterating with a single fixed column count instead of a[i].length
- Thinking jagged arrays need a special type or library
- Writing new int[][4] expecting it to compile