Methods, Arrays, and Program Structure

Two-Dimensional and Multidimensional Arrays

ReadingPreview

You are viewing a free preview lesson.

Lesson Overview

এখন পর্যন্ত আমরা one-dimensional arrays ব্যবহার করেছি।

Example:

int[] scores = {
        80,
        90,
        75
};

এখানে data এক লাইনের sequence হিসেবে আছে।

কিন্তু অনেক problem-এ data naturally row এবং column আকারে থাকে।

Example:

Student      Math    Java    English
Sakib         80      90       85
Subu          75      88       92
Sumu          91      84       89

এ ধরনের structure represent করতে Java-তে আমরা two-dimensional array ব্যবহার করতে পারি।

Example:

int[][] scores = {
        {80, 90, 85},
        {75, 88, 92},
        {91, 84, 89}
};

এই lesson-এ আমরা শিখব:

  • What a 2D array is
  • Rows and columns
  • Declaring and creating 2D arrays
  • Accessing individual cells
  • Updating values
  • Nested loops
  • Row lengths
  • Jagged arrays
  • Passing 2D arrays to methods
  • Summing rows and columns
  • Searching
  • Copying considerations
  • Multidimensional arrays beyond 2D

What Is a Two-Dimensional Array?

A two-dimensional array is an array whose elements are themselves arrays।

Example:

int[][] matrix =
        new int[3][4];

At a high level:

3 rows
4 columns per row

Conceptually:

        Column
        0   1   2   3
      +---+---+---+---+
Row 0 | 0 | 0 | 0 | 0 |
      +---+---+---+---+
Row 1 | 0 | 0 | 0 | 0 |
      +---+---+---+---+
Row 2 | 0 | 0 | 0 | 0 |
      +---+---+---+---+

2D Arrays Are Arrays of Arrays

This is important।

Java does not have a special matrix type built into the language।

This:

int[][] matrix;

means roughly:

An array containing references to int[] arrays

So conceptually:

matrix
  |
  v
+------+-------+-------+
| row0 | row1  | row2  |
+------+-------+-------+
   |       |       |
   v       v       v
 [....]  [....]  [....]

This design explains several behaviors we will see later, especially jagged arrays।


Declaring a 2D Array

Basic declaration:

int[][] matrix;

This declares a variable capable of referencing a two-dimensional int array structure।

No rows have been created yet।


Creating a Rectangular 2D Array

matrix =
        new int[3][4];

or:

int[][] matrix =
        new int[3][4];

This creates:

3 rows
4 elements in each row

Accessing a Cell

Syntax:

matrix[row][column]

Example:

matrix[0][0] =
        10;

sets the first row, first column।


More Assignments

matrix[0][0] =
        10;

matrix[0][1] =
        20;

matrix[1][0] =
        30;

matrix[2][3] =
        99;

Row and Column Indexes Start at Zero

For:

new int[3][4]

valid row indexes:

0
1
2

valid column indexes:

0
1
2
3

Last valid row:

2

Last valid column:

3

Reading a Cell

Example:

int value =
        matrix[2][3];

If that position contains:

99

then:

value = 99

2D Array Initializer Syntax

If values are known:

int[][] scores = {
        {80, 90, 85},
        {75, 88, 92},
        {91, 84, 89}
};

This is much easier to read than assigning every position separately।


Visualizing the Data

int[][] scores = {
        {80, 90, 85},
        {75, 88, 92},
        {91, 84, 89}
};

Conceptually:

        0    1    2
      +----+----+----+
0     | 80 | 90 | 85 |
      +----+----+----+
1     | 75 | 88 | 92 |
      +----+----+----+
2     | 91 | 84 | 89 |
      +----+----+----+

Then:

scores[0][1]

is:

90

and:

scores[2][0]

is:

91

First Index Means Row

In:

scores[row][column]

the first index identifies the row।

The second identifies the element inside that row।

Example:

scores[1][2]

means:

Row 1
Column 2

Array Length in 2D Arrays

For:

int[][] scores = {
        {80, 90, 85},
        {75, 88, 92},
        {91, 84, 89}
};

this:

scores.length

returns:

3

because the outer array contains three rows।


Row Length

To find the number of elements in the first row:

scores[0].length

Result:

3

Important Difference

scores.length

means:

Number of rows

while:

scores[row].length

means:

Number of elements in that particular row

Do not assume every row has the same length।


Traversing a 2D Array

To visit every cell, we usually use nested loops।

Example:

for (
        int row = 0;
        row < scores.length;
        row++
) {
    for (
            int column = 0;
            column < scores[row].length;
            column++
    ) {
        System.out.println(
                scores[row][column]
        );
    }
}

Why Nested Loops?

The outer loop traverses:

Rows

The inner loop traverses:

Elements inside the current row

Conceptually:

For every row
    For every column in that row
        Process the cell

Printing as a Grid

for (
        int row = 0;
        row < scores.length;
        row++
) {
    for (
            int column = 0;
            column < scores[row].length;
            column++
    ) {
        System.out.print(
                scores[row][column]
                + " "
        );
    }

    System.out.println();
}

Output:

80 90 85
75 88 92
91 84 89

Enhanced for with 2D Arrays

Because a 2D array is an array of arrays, we can write:

for (
        int[] row
        : scores
) {
    for (
            int value
            : row
    ) {
        System.out.print(
                value
                + " "
        );
    }

    System.out.println();
}

This is often very readable when indexes are not needed।


Read the Enhanced Loop Carefully

for (
        int[] row
        : scores
)

Each element of scores is:

int[]

Then:

for (
        int value
        : row
)

processes each integer in that row।


Updating a Cell

Example:

scores[1][2] =
        95;

Before:

75 88 92

After:

75 88 95

2D arrays are mutable just like normal arrays।


Modifying Every Cell

Example: add 5 points to every score।

for (
        int row = 0;
        row < scores.length;
        row++
) {
    for (
            int column = 0;
            column < scores[row].length;
            column++
    ) {
        scores[row][column] +=
                5;
    }
}

Enhanced for Cannot Replace Primitive Cells Directly

This:

for (
        int[] row
        : scores
) {
    for (
            int value
            : row
    ) {
        value +=
                5;
    }
}

does not update the primitive cells।

Why?

value is a local copy of each primitive element।

If you need to replace array positions, use indexes।


Calculating the Total of All Cells

static int total(
        int[][] values
) {
    int total =
            0;

    for (
            int[] row
            : values
    ) {
        for (
                int value
                : row
        ) {
            total +=
                    value;
        }
    }

    return total;
}

Example

Input:

int[][] numbers = {
        {1, 2},
        {3, 4}
};

Total:

10

Sum of One Row

static int rowSum(
        int[][] values,
        int rowIndex
) {
    int total =
            0;

    for (
            int value
            : values[rowIndex]
    ) {
        total +=
                value;
    }

    return total;
}

Usage:

rowSum(
        scores,
        0
);

calculates the first student's total score।


Average of One Row

static double rowAverage(
        int[][] values,
        int rowIndex
) {
    int[] row =
            values[rowIndex];

    if (
            row.length == 0
    ) {
        throw new IllegalArgumentException(
                "Row cannot be empty."
        );
    }

    int total =
            0;

    for (
            int value
            : row
    ) {
        total +=
                value;
    }

    return (double) total
            / row.length;
}

Column Sum

Column operations require more care।

Suppose rectangular data:

int[][] values = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
};

Column 1 contains:

2
5
8

Column Sum Method

static int columnSum(
        int[][] values,
        int columnIndex
) {
    int total =
            0;

    for (
            int row = 0;
            row < values.length;
            row++
    ) {
        total +=
                values[row][columnIndex];
    }

    return total;
}

For column 1:

15

But What About Jagged Arrays?

The previous columnSum() assumes every row contains the requested column।

That assumption is valid for a rectangular matrix, but Java also allows rows of different lengths।

This is called a:

Jagged array

Creating a Jagged Array

Example:

int[][] values = {
        {1, 2},
        {3, 4, 5},
        {6}
};

Conceptually:

Row 0 → [1, 2]
Row 1 → [3, 4, 5]
Row 2 → [6]

Rows have different lengths।


Why Is This Possible?

Because:

int[][]

is an array of:

int[]

Each row is a separate array object।

Therefore each row can have a different length।


Creating Jagged Arrays Step by Step

int[][] values =
        new int[3][];

values[0] =
        new int[2];

values[1] =
        new int[4];

values[2] =
        new int[1];

Now:

values[0].length = 2
values[1].length = 4
values[2].length = 1

Outer Array Creation Only

This:

int[][] values =
        new int[3][];

creates the outer array with three positions।

Initially:

values[0] = null
values[1] = null
values[2] = null

The row arrays must be created separately।


Accessing an Uninitialized Row

After:

int[][] values =
        new int[3][];

this fails:

values[0][0]

because:

values[0]

is still:

null

This results in:

NullPointerException

Safe Traversal of Jagged Arrays

Never assume:

values[0].length

applies to every row।

Use:

values[row].length

for each current row।

Correct:

for (
        int row = 0;
        row < values.length;
        row++
) {
    for (
            int column = 0;
            column < values[row].length;
            column++
    ) {
        System.out.println(
                values[row][column]
        );
    }
}

Common Bug

Incorrect:

for (
        int row = 0;
        row < values.length;
        row++
) {
    for (
            int column = 0;
            column < values[0].length;
            column++
    ) {
        System.out.println(
                values[row][column]
        );
    }
}

This assumes every row is as long as row 0

For jagged arrays, this may cause:

ArrayIndexOutOfBoundsException

Realistic Use for Jagged Arrays

Suppose each module contains a different number of lessons:

String[][] lessons = {
        {
                "Variables",
                "Operators",
                "Conditions"
        },
        {
                "Classes",
                "Objects"
        },
        {
                "Collections",
                "Generics",
                "Maps",
                "Sets"
        }
};

Different rows naturally contain different numbers of values।

This is a reasonable jagged structure।


Searching a 2D Array

Example:

static boolean contains(
        int[][] values,
        int target
) {
    for (
            int[] row
            : values
    ) {
        for (
                int value
                : row
        ) {
            if (
                    value == target
            ) {
                return true;
            }
        }
    }

    return false;
}

Searching for Position

Sometimes we want both row and column։

We could return two numbers eventually using an object or array।

For now:

static void printPosition(
        int[][] values,
        int target
) {
    for (
            int row = 0;
            row < values.length;
            row++
    ) {
        for (
                int column = 0;
                column < values[row].length;
                column++
        ) {
            if (
                    values[row][column]
                    == target
            ) {
                System.out.println(
                        "Found at row "
                        + row
                        + ", column "
                        + column
                );

                return;
            }
        }
    }

    System.out.println(
            "Not found"
    );
}

Later, domain objects or records give cleaner ways to return structured results।


Finding Maximum in a 2D Array

A complication:

What if the outer array is empty?
What if rows are empty?
What if rows are null?

For a simple learning version, assume:

At least one row contains at least one value

Then:

static int max(
        int[][] values
) {
    boolean found =
            false;

    int max =
            0;

    for (
            int[] row
            : values
    ) {
        for (
                int value
                : row
        ) {
            if (
                    !found
                    || value > max
            ) {
                max =
                        value;

                found =
                        true;
            }
        }
    }

    if (!found) {
        throw new IllegalArgumentException(
                "Array contains no values."
        );
    }

    return max;
}

This works even when all values are negative।


Why Not Initialize max = values[0][0]?

For a rectangular non-empty matrix, that's fine।

But with jagged arrays:

values[0]

could be empty।

Using:

found flag

allows us to handle empty rows more safely।


Counting Values Matching a Condition

Example: count values greater than 50

static int countGreaterThan(
        int[][] values,
        int threshold
) {
    int count =
            0;

    for (
            int[] row
            : values
    ) {
        for (
                int value
                : row
        ) {
            if (
                    value > threshold
            ) {
                count++;
            }
        }
    }

    return count;
}

Again, the same traversal patterns from one-dimensional arrays still apply।


Nested Traversal Pattern

The general pattern:

for (
        int[] row
        : values
) {
    for (
            int value
            : row
    ) {
        // process value
    }
}

is simply:

Traversal inside traversal

This is why nested loops appear naturally with multidimensional data।


Complexity Preview

Suppose there are:

R rows
C columns in each row

Visiting every cell means roughly:

R × C operations

For a square matrix where:

R = n
C = n

that becomes approximately:

We'll formalize this using Big-O later।


Copying a 2D Array

This is more subtle than copying a one-dimensional primitive array।

Suppose:

int[][] original = {
        {1, 2},
        {3, 4}
};

Then:

int[][] copy =
        original;

does not copy anything except the outer reference।

Both variables reference the exact same structure।


Shallow Outer Copy

Suppose:

int[][] copy =
        original.clone();

Now the outer arrays are different।

But their row references still point to the same row arrays।

Conceptually:

original outer ----+
                   |
                   +--> row0 [1,2]
                   +--> row1 [3,4]

copy outer --------+
                   |
                   +--> same row0
                   +--> same row1

Why This Matters

After a shallow outer copy:

copy[0][0] =
        999;

then:

original[0][0]

also becomes:

999

because row 0 is shared।


Deep Copy for Primitive 2D Arrays

To create independent rows:

static int[][] copy(
        int[][] original
) {
    int[][] result =
            new int[
                    original.length
            ][];

    for (
            int row = 0;
            row < original.length;
            row++
    ) {
        result[row] =
                original[row].clone();
    }

    return result;
}

For primitive row elements, this gives an independent 2D structure।


Jagged Shape Is Preserved

Because each row is copied separately:

result[row] =
        original[row].clone();

a jagged structure remains jagged।

Example:

2 elements
4 elements
1 element

is preserved।


What If a Row Is null?

A more defensive copy:

static int[][] copy(
        int[][] original
) {
    int[][] result =
            new int[
                    original.length
            ][];

    for (
            int row = 0;
            row < original.length;
            row++
    ) {
        if (
                original[row] != null
        ) {
            result[row] =
                    original[row].clone();
        }
    }

    return result;
}

Whether null rows should be supported is part of the method's contract।


Passing 2D Arrays to Methods

A parameter looks like:

static void printMatrix(
        int[][] matrix
)

Call:

printMatrix(
        scores
);

Just like one-dimensional arrays, Java passes the reference value by value।

The method can mutate the shared underlying arrays unless it creates copies।


Mutation Example

static void clear(
        int[][] values
) {
    for (
            int row = 0;
            row < values.length;
            row++
    ) {
        for (
                int column = 0;
                column < values[row].length;
                column++
        ) {
            values[row][column] =
                    0;
        }
    }
}

Caller data is modified because both caller and method refer to the same arrays।


Rectangular Matrix Operations

For proper matrix operations, dimensions matter।

Example matrix:

int[][] matrix = {
        {1, 2},
        {3, 4}
};

Some common operations include:

Row sum
Column sum
Transpose
Diagonal sum
Matrix addition

We'll do a few foundational examples।


Main Diagonal

In a square matrix:

1 2 3
4 5 6
7 8 9

main diagonal:

1 5 9

Positions:

[0][0]
[1][1]
[2][2]

Diagonal Sum

static int diagonalSum(
        int[][] matrix
) {
    int total =
            0;

    for (
            int i = 0;
            i < matrix.length;
            i++
    ) {
        total +=
                matrix[i][i];
    }

    return total;
}

This assumes a square matrix with enough columns in each row।


Validate Square Matrix

A safer method:

static boolean isSquare(
        int[][] matrix
) {
    for (
            int[] row
            : matrix
    ) {
        if (
                row.length
                != matrix.length
        ) {
            return false;
        }
    }

    return true;
}

Then matrix-specific operations can reject invalid shape।


Matrix Addition

Two matrices can be added when they have the same dimensions।

Example:

A              B

1 2            5 6
3 4            7 8

Result:

6  8
10 12

Java Implementation

static int[][] add(
        int[][] first,
        int[][] second
) {
    if (
            first.length
            != second.length
    ) {
        throw new IllegalArgumentException(
                "Row counts must match."
        );
    }

    int[][] result =
            new int[
                    first.length
            ][];

    for (
            int row = 0;
            row < first.length;
            row++
    ) {
        if (
                first[row].length
                != second[row].length
        ) {
            throw new IllegalArgumentException(
                    "Row lengths must match."
            );
        }

        result[row] =
                new int[
                        first[row].length
                ];

        for (
                int column = 0;
                column < first[row].length;
                column++
        ) {
            result[row][column] =
                    first[row][column]
                    + second[row][column];
        }
    }

    return result;
}

This version even supports compatible jagged shapes।


Transpose Concept

For a rectangular matrix:

1 2 3
4 5 6

transpose becomes:

1 4
2 5
3 6

Rows become columns।

This is easiest with rectangular arrays।


Transpose Implementation

static int[][] transpose(
        int[][] matrix
) {
    if (
            matrix.length == 0
    ) {
        return new int[0][0];
    }

    int columns =
            matrix[0].length;

    for (
            int[] row
            : matrix
    ) {
        if (
                row.length
                != columns
        ) {
            throw new IllegalArgumentException(
                    "Matrix must be rectangular."
            );
        }
    }

    int[][] result =
            new int[
                    columns
            ][
                    matrix.length
            ];

    for (
            int row = 0;
            row < matrix.length;
            row++
    ) {
        for (
                int column = 0;
                column < columns;
                column++
        ) {
            result[column][row] =
                    matrix[row][column];
        }
    }

    return result;
}

You do not need to memorize this।

The important idea is:

Nested loops + index relationships

Arrays Beyond Two Dimensions

Java supports more dimensions।

Example:

int[][][] data =
        new int[2][3][4];

This can be thought of as:

An array
of arrays
of arrays
of int

Accessing a 3D Element

data[0][1][2] =
        99;

Three indexes identify:

Layer
Row
Column

depending on your conceptual model।


3D Initializer Example

int[][][] values = {
        {
                {1, 2},
                {3, 4}
        },
        {
                {5, 6},
                {7, 8}
        }
};

Traversing a 3D Array

for (
        int[][] matrix
        : values
) {
    for (
            int[] row
            : matrix
    ) {
        for (
                int value
                : row
        ) {
            System.out.println(
                    value
            );
        }
    }
}

Each dimension generally adds another level of traversal।


Do You Often Need 4D or 5D Arrays?

Usually not in ordinary backend application code।

Multidimensional arrays are useful for understanding:

Nested data
Matrices
Grids
Boards
Images
Coordinates
Algorithmic problems

But complex business data is usually better represented using domain objects and collections।


Example: Chess Board

A board can conceptually be represented as:

String[][] board =
        new String[8][8];

Each position:

board[row][column]

represents one square।

For a real chess application, richer objects would eventually be more appropriate।


Example: Cinema Seats

boolean[][] seats =
        new boolean[5][10];

Could represent:

false → available
true  → booked

For a small exercise, this is fine।

In a real system, a Seat domain model might be clearer।


Example: Classroom Scores

int[][] scores = {
        {80, 85, 90},
        {70, 75, 80},
        {95, 92, 91}
};

Here:

Row → student
Column → subject

The meaning exists because our application defines it।

Java itself only sees nested arrays।


Data Structure Should Match the Domain

Just because you can represent something as:

String[][]

does not mean you always should।

Suppose you store:

Course code
Course title
Price
Status

as:

String[][] courses

This becomes difficult to understand:

courses[3][2]

What does that mean?

A class like:

Course

will later provide much clearer modeling।

Arrays are excellent for sequences and grid-like data, but weak at expressing rich domain concepts।


Common Beginner Mistake 1: Using One Length for Everything

Incorrect:

for (
        int row = 0;
        row < values.length;
        row++
) {
    for (
            int column = 0;
            column < values.length;
            column++
    ) {
    }
}

This assumes:

number of rows == number of columns

which may not be true।

Correct:

column < values[row].length

Common Beginner Mistake 2: Confusing Row and Column

matrix[column][row]

instead of:

matrix[row][column]

can produce wrong results or exceptions।

Use clear variable names:

row
column

instead of always:

i
j

while learning।


Common Beginner Mistake 3: Assuming Every 2D Array Is Rectangular

Java supports jagged arrays।

Always ask:

Can row lengths differ?

before writing algorithms that assume a matrix shape।


Common Beginner Mistake 4: Accessing Null Rows

After:

int[][] values =
        new int[3][];

the row references are initially null।

You must initialize them before element access।


Common Beginner Mistake 5: Shallow Copy Assumption

This:

int[][] copy =
        original.clone();

does not create independent copies of all row arrays।

It only copies the outer array।


Common Beginner Mistake 6: Enhanced Loop Mutation

This:

for (
        int[] row
        : matrix
) {
    for (
            int value
            : row
    ) {
        value =
                0;
    }
}

does not clear primitive elements।

Use indexed assignments।


Common Beginner Mistake 7: Empty First Row Assumptions

Code such as:

int columns =
        matrix[0].length;

requires:

matrix.length > 0

and:

matrix[0] != null

Your method contract must define these assumptions or validate them।


Practical Example: Student Score Report

public class Main {

    public static void main(String[] args) {
        int[][] scores = {
                {80, 90, 85},
                {75, 88, 92},
                {91, 84, 89}
        };

        printScores(
                scores
        );

        for (
                int student = 0;
                student < scores.length;
                student++
        ) {
            System.out.println(
                    "Student "
                    + student
                    + " average: "
                    + average(
                            scores[student]
                    )
            );
        }
    }

    static void printScores(
            int[][] scores
    ) {
        for (
                int[] row
                : scores
        ) {
            for (
                    int score
                    : row
            ) {
                System.out.print(
                        score
                        + " "
                );
            }

            System.out.println();
        }
    }

    static double average(
            int[] values
    ) {
        if (
                values.length == 0
        ) {
            throw new IllegalArgumentException(
                    "Values cannot be empty."
            );
        }

        int total =
                0;

        for (
                int value
                : values
        ) {
            total +=
                    value;
        }

        return (double) total
                / values.length;
    }
}

This demonstrates an important reuse idea:

A row of a 2D int array is itself an int[].

Therefore our one-dimensional average() method works directly on each row।


Practice 1: Create a Matrix

Create a 2D array representing:

1 2 3
4 5 6

Solution

int[][] matrix = {
        {1, 2, 3},
        {4, 5, 6}
};

Practice 2: Access a Cell

Using:

int[][] matrix = {
        {10, 20, 30},
        {40, 50, 60}
};

print:

50

Solution

System.out.println(
        matrix[1][1]
);

Practice 3: Print All Values

Write nested loops to print every value।


Solution

for (
        int row = 0;
        row < matrix.length;
        row++
) {
    for (
            int column = 0;
            column < matrix[row].length;
            column++
    ) {
        System.out.println(
                matrix[row][column]
        );
    }
}

Practice 4: Sum a Row

Given:

int[][] values = {
        {1, 2, 3},
        {10, 20, 30}
};

calculate the total of row 1


Solution

int total =
        0;

for (
        int value
        : values[1]
) {
    total +=
            value;
}

Result:

60

Practice 5: Count All Elements

Write a method that returns the total number of actual cells, including jagged arrays।

Example:

{
    {1, 2},
    {3, 4, 5},
    {6}
}

should return:

6

Solution

static int countElements(
        int[][] values
) {
    int count =
            0;

    for (
            int[] row
            : values
    ) {
        count +=
                row.length;
    }

    return count;
}

Practice 6: Jagged Array

Create rows of lengths:

2
4
1

Solution

int[][] values =
        new int[3][];

values[0] =
        new int[2];

values[1] =
        new int[4];

values[2] =
        new int[1];

Practice 7: Find Target

Write:

static boolean contains(
        String[][] values,
        String target
)

Solution

static boolean contains(
        String[][] values,
        String target
) {
    for (
            String[] row
            : values
    ) {
        for (
                String value
                : row
        ) {
            if (
                    value.equals(
                            target
                    )
            ) {
                return true;
            }
        }
    }

    return false;
}

Practice 8: Main Diagonal

Given:

int[][] matrix = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
};

print the main diagonal।


Solution

for (
        int i = 0;
        i < matrix.length;
        i++
) {
    System.out.println(
            matrix[i][i]
    );
}

Output:

1
5
9

Practice 9: Predict the Output

int[][] values = {
        {1, 2},
        {3, 4, 5}
};

System.out.println(
        values.length
);

System.out.println(
        values[1].length
);

Answer

2
3

There are two rows, and row 1 contains three elements।


Practice 10: Shallow Copy

Predict:

int[][] first = {
        {1, 2},
        {3, 4}
};

int[][] second =
        first.clone();

second[0][0] =
        99;

System.out.println(
        first[0][0]
);

Answer

99

The outer array was copied, but the row arrays are still shared।


True or False

  1. A Java 2D array is fundamentally an array of arrays.
  2. matrix.length always means number of columns.
  3. matrix[row].length gives that row's length.
  4. Every Java 2D array must be rectangular.
  5. Rows of a jagged array may have different sizes.
  6. new int[3][] fully creates all inner row arrays.
  7. Nested loops are common for traversing 2D arrays.
  8. A row of int[][] has type int[].
  9. matrix.clone() performs a full deep copy.
  10. Java can represent three-dimensional arrays.
  11. Every matrix-like problem should be modeled using arrays.
  12. Enhanced loops are convenient when indexes are unnecessary.

Answers

1. True
2. False
3. True
4. False
5. True
6. False
7. True
8. True
9. False
10. True
11. False
12. True

Knowledge Check

Question 1

What does int[][] mean conceptually?

Question 2

In matrix[row][column], what does each index represent?

Question 3

What does matrix.length return?

Question 4

What does matrix[row].length return?

Question 5

Why do nested loops naturally fit 2D array traversal?

Question 6

What is a jagged array?

Question 7

Why can different rows have different lengths in Java?

Question 8

What happens to row references after new int[3][]?

Question 9

Why should algorithms use matrix[row].length instead of assuming one column count?

Question 10

Why is cloning only the outer array a shallow copy?

Question 11

When might a 2D array be appropriate?

Question 12

When should a class or richer domain structure be preferred instead?


Knowledge Check Answers

Answer 1

It means an array whose elements are references to int[] arrays।

Answer 2

The first index selects a row, and the second selects an element inside that row।

Answer 3

The number of elements in the outer array, usually interpreted as the row count।

Answer 4

The number of elements in that specific row।

Answer 5

One loop selects each row while another loop processes the elements inside the current row।

Answer 6

A two-dimensional array whose row arrays have different lengths।

Answer 7

Because each row is a separate array object referenced by the outer array।

Answer 8

They initially contain null until individual row arrays are assigned।

Answer 9

Because Java allows jagged arrays, so different rows may have different lengths।

Answer 10

The new outer array still contains references to the same inner row arrays।

Answer 11

For naturally grid-like, matrix-like, board-like, or nested fixed-size data where positional access is useful।

Answer 12

When the data represents rich concepts with named properties, behavior, lifecycle, or relationships that indexes cannot communicate clearly।


Lesson Summary

এই lesson-এ আমরা one-dimensional arrays থেকে nested array structures-এ গিয়েছি।

We learned:

  • int[][] is an array of int[] arrays
  • Two-dimensional data is commonly viewed as rows and columns
  • Both row and column indexes start at 0
  • matrix.length gives the outer array length
  • matrix[row].length gives a specific row length
  • Nested loops are the standard traversal pattern
  • Enhanced loops can make value-only traversal cleaner
  • Indexed loops are needed for direct cell replacement
  • Rows can be processed independently because each row is itself an array
  • Java supports jagged arrays with different row lengths
  • new int[3][] creates only the outer array
  • Uninitialized rows remain null
  • Matrix-specific algorithms may require rectangular or square shape validation
  • Row sums, column sums, search, diagonal traversal, addition, and transpose all build on nested traversal
  • 2D arrays are mutable reference structures
  • Copying only the outer array is shallow
  • Independent nested arrays require copying the row arrays too
  • Java supports arrays with three or more dimensions
  • Multidimensional arrays are useful for positional data but should not replace proper domain modeling

The central idea is:

A 2D array is not magic.

It is simply an array
whose elements are other arrays.

Once this model is clear, rectangular arrays, jagged arrays, nested traversal, and copying behavior become much easier to understand।


Next Lesson

পরবর্তী lesson:

The Arrays Utility Class and Common Array Operations

আমরা শিখব:

  • java.util.Arrays
  • Arrays.toString()
  • Arrays.deepToString()
  • Arrays.equals()
  • Arrays.deepEquals()
  • Arrays.copyOf()
  • Arrays.copyOfRange()
  • Arrays.fill()
  • Arrays.sort()
  • Arrays.binarySearch()
  • Why built-in utilities are usually preferable to rewriting common operations
  • How these APIs connect to the Algorithms module