2D arrays in Java, explained for AP Computer Science A
A 2D array stores data in a grid of rows and columns, like a spreadsheet or a game board. AP Computer Science A tests 2D arrays every year, usually as one of the four free-response questions.
On this page
What a 2D array is
In Java, a 2D array is an array of arrays. The outer array holds the rows, and each row is itself an array of values. Think of a seating plan: seats[r][c] is the seat in row r and column c. Both indexes start at 0.
Declaring and creating
int[][] grid = new int[3][4]; // 3 rows, 4 columns, all 0
String[][] board = new String[8][8]; // all null
int[][] scores = { {90, 85, 77},
{60, 72, 88} }; // 2 rows, 3 columns
When created with new, elements get default values: 0 for int, 0.0 for double, false for boolean and null for objects such as String.
Rows and columns
grid.lengthis the number of rows.grid[0].lengthis the number of columns (the length of the first row).grid[r][c]is the element in row r, column c.
On the AP exam, 2D arrays are rectangular: every row has the same length. The last valid element is grid[grid.length - 1][grid[0].length - 1].
Row-major traversal
The standard pattern visits each row in turn, left to right. The outer loop goes over rows and the inner loop over columns.
for (int r = 0; r < grid.length; r++)
{
for (int c = 0; c < grid[0].length; c++)
{
System.out.print(grid[r][c] + " ");
}
System.out.println();
}
Column-major traversal
To go down each column in turn, swap the loops: the outer loop goes over columns and the inner loop over rows. The element access is still grid[r][c]; only the loop order changes.
for (int c = 0; c < grid[0].length; c++)
{
for (int r = 0; r < grid.length; r++)
{
System.out.print(grid[r][c] + " ");
}
}
Enhanced for loops
For read-only access, nested enhanced for loops are tidy. The outer loop variable is a whole row, which is a 1D array.
int total = 0;
for (int[] row : grid)
{
for (int value : row)
{
total += value;
}
}
You cannot use an enhanced for loop to change the elements of an int array, because the loop variable is a copy of each value. Use index loops when you need to assign.
Worked examples
Example 1: row sums
Write a method that returns an array containing the sum of each row of a 2D int array.
public static int[] rowSums(int[][] arr) { int[] sums = new int[arr.length]; for (int r = 0; r < arr.length; r++) { for (int c = 0; c < arr[0].length; c++) { sums[r] += arr[r][c]; } } return sums; }- The result has one entry per row, so its length is arr.length.
Example 2: counting matches
Count how many elements of a String[][] called board equal "X".
int count = 0; for (String[] row : board) { for (String s : row) { if ("X".equals(s)) { count++; } } }- Writing "X".equals(s) instead of s.equals("X") avoids an error if some elements are null.
Example 3: checking neighbours
Return true if the cell at (r, c) has a neighbour directly above it with the same value.
public static boolean sameAbove(int[][] g, int r, int c) { return r > 0 && g[r - 1][c] == g[r][c]; }- Check r > 0 first. Because && short-circuits, g[r - 1][c] is never evaluated for the top row, so there is no out-of-bounds error.
Example 4: tracing
int[][] m = { {1, 2, 3}, {4, 5, 6} };
int s = 0;
for (int c = 0; c < m[0].length; c++)
{
s += m[1][c] - m[0][c];
}
System.out.println(s);- Each column contributes 3: (4 − 1) + (5 − 2) + (6 − 3).
- Printed: 9.
Example 5: location of the largest value
Return the row index of the row that contains the largest value in a non-empty int[][] called g.
int bestRow = 0; int max = g[0][0]; for (int r = 0; r < g.length; r++) { for (int c = 0; c < g[0].length; c++) { if (g[r][c] > max) { max = g[r][c]; bestRow = r; } } } return bestRow;- Track both the best value and where it was found. Starting max at g[0][0], not 0, keeps the method correct when every value is negative.
How to plan a 2D array answer
Before writing code, decide three things. First, which traversal order you need: rows first, columns first, or just one row or column. Second, what you are accumulating or searching for, and what its starting value should be. Third, what you return, and when. Writing these three decisions as short comments at the top of your answer keeps the code organised and helps readers award partial credit if something goes wrong. Partial credit is generous for a correct traversal with a small mistake in the condition, so a clear structure is worth a lot.
Common FRQ patterns
2D array free-response questions often ask you to: total or average a row or column; find the location of the largest value; check whether a row meets a condition; copy values into a new array of a different shape; or work with neighbouring cells in a game board. Many questions describe a class that wraps a 2D array as an instance variable, so read carefully whether you should use the instance variable directly or a method the class provides.
Common mistakes
- Swapping rows and columns: grid.length is rows, grid[0].length is columns.
- Using grid.length for the inner loop bound when the array is not square.
- Going out of bounds when checking neighbours; check the edge first.
- Trying to modify values through an enhanced for loop variable.
- Writing grid[r, c] instead of grid[r][c].
Practice questions
Try each one before opening the answer.
Q1. int[][] a = new int[4][6]; What are a.length and a[0].length?
Show answer
Q2. What is the default value of each element in new double[2][2]?
Show answer
Q3. Given int[][] t = { {2, 4}, {6, 8}, {10, 12} };, what is t[2][0] + t[0][1]?
Show answer
Q4. How would you get the last column index of a rectangular 2D array g?
Show answer
Frequently asked questions
Are 2D arrays on the AP CSA exam?
Yes. 2D arrays are part of the Data Collections unit in the revised AP Computer Science A course, and one of the four free-response questions is usually built around a 2D array.
Do I need to know jagged arrays?
AP questions use rectangular 2D arrays, where every row has the same length. Understanding that each row is a separate array is still helpful.
Key takeaways
- A 2D array is an array of rows.
- grid.length is rows; grid[0].length is columns.
- Row-major: rows outside, columns inside.
- Column-major: swap the loops, keep grid[r][c].
- Check bounds before accessing neighbours.