MT2 - 2D Arrays
What is a 2D array?
A regular array is a single row of values:
int[] numbers = {10, 20, 30, 40};
A 2D array is essentially an array of arrays. Think of it like a table with rows and columns.
In java:
int[][] numbers = {
{10, 20, 30, 40},
{50, 60, 70, 80},
{90, 100, 110, 120}
};
How do we access values?
This is the most important rule:
numbers[row][column]
First number = row
Second number = column
For example:
numbers[0][0] // 10
numbers[0][2] // 30
numbers[1][1] // 60
numbers[2][3] // 120
Remember: Java starts counting at zero for BOTH rows and columns.
How do .length values work
This is where people get tripped up.
numbers.length
Gives you the number of rows: 3
numbers[0].length
Gives you number of columns in row 0: 4
Creating an empty 2D array
You can also create one without putting values in it:
int[][] scores = new int[3][4];
This creates an array with 3 rows 4 columns
Nested Loops
Why do we need nested loops?
With a regular array, one loop is enough
int[] numbers = {10, 20, 30, 40};
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
But a 2D array has multiple rows AND columns
We need:
An outer loop to move between rows.
An inner loop to move through the columns in each row.
That's called a nested loop: a loop inside another loop.
The basic structure
for (int i = 0; i < numbers.length; i++) {
for (int j = 0; j < numbers[i].length; j++) {
System.out.println(numbers[i][j]);
}
}
i represents the current row, j represents column in that row
What if we want to calculate the sum?
Same nested loops, we js add an accumulator
int sum = 0;
for (int i = 0; i < numbers.length; i++) {
for (int j = 0; j < numbers[i].length; j++) {
sum += numbers[i][j];
}
}
System.out.println(sum);
Output:
210
Filling a 2D array
So far, we've been reading values already inside an array. But what if we want Java to populate the array ourselves?
Consider:
int[][] numbers = new int[3][4];
This creates 3 rows and 4 columns, all initially filled with zeroes.
We can use nested loops to fill it:
for (int i = 0; i < numbers.length; i++) {
for (int j = 0; j < numbers[i].length; j++) {
numbers[i][j] = i + j;
}
}
What’s happening?
i tells us what row
j tells us which column
i + j determines value placed in that position
The resulting array:
Column 0 | Column 1 | Column 2 | Column 3 | |
|---|---|---|---|---|
Row 0 | 0 | 1 | 2 | 3 |
Row 1 | 1 | 2 | 3 | 4 |
Row 2 | 2 | 3 | 4 | 5 |
The important takeaway: You can use i and j to calculate what gets stored at every position.
Row Sums vs Column Sums
Imagine this array represents scores from 3 students across 4 exams:
int[][] scores = {
{80, 90, 70, 85},
{95, 75, 85, 90},
{60, 80, 90, 95}
};
Calculating row sums:
Suppose we want the total score for each student.
We need to:
Choose a row.
Go through every column in that row.
Add the values
Here’s how that looks like:
for (int i = 0; i < scores.length; i++) {
int sum = 0
for (int j = 0; j < scores[i].length; j++) {
sum += scores[i][j];
}
System.out.println(sum);
}
Output:
325
345
325
Notice where int sum = 0 is located.
It’s inside the outer loop
Why? Because we want to reset the sum for every new student. Otherwise, we'd keep adding to the previous student's total.
Calculating column sums
Now let's calculate the total score for each exam.
This time, we reverse the order of our loops.
for (int j = 0; j < scores[0].length; j++) {
int sum = 0;
for (int i = 0; i < scores.length; i++) {
sum += scores[i][j];
}
System.out.println(sum);
}
Output:
235
245
245
270
The trick to remember:
Rows: outer loop goes through rows.
Columns: outer loop goes through columns.
Calculating Averages
Once you know how to calculate sums, averages are easy.
Average = Sum / Number of Values
For each student’s average:
double average = (double) sum / scores[i].length;
For each exam’s average:
double average = (double) sum / scores.length;
Why are the denominators different?
A row has as many values as there are columns
A column has as many values as there are rows
Finding row or column with highest sum
What’s the goal?
Suppose we have:
int[][] scores = {
{10, 20, 30},
{40, 50, 60},
{70, 80, 90}
};
We want to find which row has the highest total.
First, calculate each row:
Row | Calculation | Sum |
|---|---|---|
0 | 10 + 20 + 30 | 60 |
1 | 40 + 50 + 60 | 150 |
2 | 70 + 80 + 90 | 240 |
So row 2 wins, with 240.
How do we make java find it?
First we need two variables:
int maxSum = Integer.MIN_VALUE;
int maxRow = -1;
maxSumstores the highest sum we've found so far.maxRowremembers which row produced that sum.Integer.MIN_VALUEstarts us at the smallest possible integer, so even negative row sums work.
Now the loop:
for (int i = 0; int < scores.length; i++) {
int sum = 0
for (int j = 0; int < scores[i].length; j++; {
sum += scores[i][j];
}
if (sum > maxSum) {
maxSum = sum;
maxRow = i;
}
}
Let’s understand the logic:
Step 1: Calculate current row’s sum
Step 2: Compare it with highest sum we’ve seen
Step 3: If the current sum is bigger, update both variables.
That's it. We repeat for every row.
At the end:
System.out.println(maxRow);
System.out.println(maxSum);
Output:
2
240
What if we want the highest column sum?
Same exact idea but switch the loops around
int maxSum = Integer.MIN_VALUE;
int maxColumn = -1;
for (int j = 0; j < scores[0].length; j++) {
int sum = 0;
for (int i = 0; i < scores.length; i++) {
sum += scores[i][j];
}
if (sum > maxSum) {
maxSum = sum;
maxColumn = j;
}
}
Ragged Arrays
What is a ragged array?
So far, all our 2D arrays have been rectangular: every row has the same number of columns.
But Java allows rows to have different lengths.
That's called a ragged array.
Example:
int[][] numbers = {
{10, 20, 30},
{40, 50},
{60, 70, 80, 90}
};
Notice:
Row 0 has 3 elements.
Row 1 has 2 elements.
Row 2 has 4 elements.
How does .length work now?
numbers.length // 3
numbers[0].length // 3
numbers[1].length // 2
numbers[2].length // 4
The first .length tells us how many rows
Second .length tells us how many columns in the rows
Why does this matter for loops?
For regular rectangular arrays, you might see:
for (int i = 0; i < numbers.length; i++) {
for (int j = 0; j < numbers[0].length; j++) {
System.out.println(numbers[i][j]);
}
}
But with ragged arrays this could cause an error.
Why?
Because numbers[0].length is 3. When the loop reaches row 2, that row has 4 elements, so the fourth element never gets visited.
And if a row is shorter than row 0, accessing a nonexistent position can cause an error.
The safer approach is:
for (int i = 0; i < numbers.length; i++) {
for (int j = 0; j < numbers[i].length; j++) {
System.out.println(numbers[i][j]);
}
}
Always use numbers[i].length when looping through each row.