Methods, Arrays, and Program Structure

Traversing and Working with Arrays

ReadingPreview

You are viewing a free preview lesson.

Lesson Overview

আগের lesson-এ আমরা arrays-এর basic structure শিখেছি।

আমরা জানি:

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

এবং individual elements access করতে পারি:

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

কিন্তু real programs-এ array-এর প্রতিটি element manually access করা practical নয়।

যদি array-তে 1000 elements থাকে?

তখন আমাদের দরকার:

Traversal

Traversal means:

Array-এর elements একে একে process করা।

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

  • Indexed for loop
  • Enhanced for loop
  • while loop দিয়ে traversal
  • Index vs value
  • Reading and modifying elements
  • Sum and average
  • Minimum and maximum
  • Counting
  • Searching
  • Filtering-like traversal
  • Reversing an array
  • Copying arrays
  • Comparing traversal styles
  • Common array-processing patterns

What Is Array Traversal?

Suppose:

int[] scores = {
        82,
        91,
        76,
        88
};

Traversal means processing:

82
91
76
88

one after another।

The most common ways are:

Indexed for loop
Enhanced for loop
while loop

Indexed for Loop

The classic traversal pattern:

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

Output:

82
91
76
88

Understanding the Loop

int i = 0;

starts from the first index।

i < scores.length;

continues while i is a valid index।

i++;

moves to the next index।

Then:

scores[i]

accesses the element at that index।


Index and Value Are Different

In:

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

i is:

Index

while:

scores[i]

is:

Value

Example:

i = 0 → scores[0] = 82
i = 1 → scores[1] = 91
i = 2 → scores[2] = 76
i = 3 → scores[3] = 88

Printing Index and Value

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

Output:

Index 0 = 82
Index 1 = 91
Index 2 = 76
Index 3 = 88

Why Indexed Traversal Is Powerful

An indexed loop is useful when you need:

The element position
To update elements
To compare neighboring elements
To traverse backwards
To skip positions

Updating Elements

Example:

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

for (
        int i = 0;
        i < numbers.length;
        i++
) {
    numbers[i] =
            numbers[i] * 2;
}

Array becomes:

2
4
6
8

Enhanced for Loop

Java provides a simpler traversal syntax:

for (
        int score
        : scores
) {
    System.out.println(
            score
    );
}

This is often called:

Enhanced for loop

or:

for-each loop

Reading the Syntax

for (
        int score
        : scores
)

means roughly:

For each int value named score
inside scores

Enhanced Loop Example

String[] courses = {
        "Java",
        "Backend Development",
        "System Design"
};

for (
        String course
        : courses
) {
    System.out.println(
            course
    );
}

Output:

Java
Backend Development
System Design

When Enhanced for Is Better

Use it when you only need:

Each value

and do not care about:

Index
Direct element replacement
Traversal direction

It is concise and usually easier to read।


Enhanced for Does Not Give the Index

This loop:

for (
        int score
        : scores
)

gives you:

score

but not:

0
1
2
3

If you need the index, use an indexed loop।


Can Enhanced for Modify the Array?

Consider:

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

for (
        int number
        : numbers
) {
    number =
            number * 10;
}

After the loop, the array is still:

1
2
3

Why?

number is a local variable containing a copy of each primitive element value।

Changing:

number

does not replace:

numbers[index]

Correct Way to Modify Primitive Elements

Use indexes:

for (
        int i = 0;
        i < numbers.length;
        i++
) {
    numbers[i] =
            numbers[i] * 10;
}

Result:

10
20
30

Enhanced for with Reference Types

Later, when arrays contain mutable objects, an enhanced loop can still call methods on those objects because the local variable receives a copy of the object reference।

But assigning a new reference to the loop variable still does not replace the array element itself।

We'll revisit that after learning objects।


Traversing with while

Arrays can also be traversed using while

int i =
        0;

while (
        i < scores.length
) {
    System.out.println(
            scores[i]
    );

    i++;
}

This works, but for straightforward index traversal:

for

is usually clearer because initialization, condition, and increment are together।


Which Loop Should You Use?

A useful rule:

Need index?
→ indexed for loop

Only need values?
→ enhanced for loop

Loop control is unusual or condition-driven?
→ while may be appropriate

Calculating a Sum

A very common array operation is accumulation।

Suppose:

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

We want:

240

Sum with Enhanced for

int total =
        0;

for (
        int score
        : scores
) {
    total +=
            score;
}

After traversal:

total = 240

Accumulator Pattern

This pattern:

int total =
        0;

for (...) {
    total += value;
}

is called an:

Accumulator pattern

We start with an initial result and update it during traversal।


Complete Sum Method

static int sum(
        int[] numbers
) {
    int total =
            0;

    for (
            int number
            : numbers
    ) {
        total +=
                number;
    }

    return total;
}

Usage:

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

System.out.println(
        sum(
                values
        )
);

Output:

60

Calculating Average

Average:

sum / number of values

Example:

static double average(
        int[] numbers
) {
    int total =
            0;

    for (
            int number
            : numbers
    ) {
        total +=
                number;
    }

    return (double) total
            / numbers.length;
}

Why Cast to double?

Without:

(double)

both operands may be integers:

5 / 2

resulting in:

2

instead of:

2.5

With:

(double) total

the division becomes floating-point division।


Empty Array Problem

What happens here?

average(
        new int[0]
);

Then:

numbers.length

is:

0

and division by zero becomes a problem।

A method should define its contract।

Example:

static double average(
        int[] numbers
) {
    if (
            numbers.length == 0
    ) {
        throw new IllegalArgumentException(
                "Cannot calculate average of an empty array."
        );
    }

    int total =
            0;

    for (
            int number
            : numbers
    ) {
        total +=
                number;
    }

    return (double) total
            / numbers.length;
}

Finding the Maximum

Suppose:

int[] numbers = {
        12,
        7,
        40,
        15
};

Maximum is:

40

A common approach:

int max =
        numbers[0];

for (
        int i = 1;
        i < numbers.length;
        i++
) {
    if (
            numbers[i] > max
    ) {
        max =
                numbers[i];
    }
}

Why Start with numbers[0]?

We need a real array value as the initial maximum।

This avoids choosing an arbitrary value like:

0

which would fail for an all-negative array।


Bad Maximum Initialization

Consider:

int max =
        0;

int[] numbers = {
        -10,
        -2,
        -30
};

No value is greater than zero।

So max incorrectly remains:

0

even though 0 is not in the array।


Correct Maximum Method

static int max(
        int[] numbers
) {
    if (
            numbers.length == 0
    ) {
        throw new IllegalArgumentException(
                "Array cannot be empty."
        );
    }

    int max =
            numbers[0];

    for (
            int i = 1;
            i < numbers.length;
            i++
    ) {
        if (
                numbers[i] > max
        ) {
            max =
                    numbers[i];
        }
    }

    return max;
}

Finding the Minimum

Same pattern:

static int min(
        int[] numbers
) {
    if (
            numbers.length == 0
    ) {
        throw new IllegalArgumentException(
                "Array cannot be empty."
        );
    }

    int min =
            numbers[0];

    for (
            int i = 1;
            i < numbers.length;
            i++
    ) {
        if (
                numbers[i] < min
        ) {
            min =
                    numbers[i];
        }
    }

    return min;
}

Searching an Array

Suppose:

String[] courses = {
        "Java",
        "Backend Development",
        "System Design"
};

We want to know whether:

Backend Development

exists।


Simple Linear Search

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

    return false;
}

Usage:

boolean found =
        contains(
                courses,
                "Backend Development"
        );

Result:

true

Why Return Early?

As soon as we find the target:

return true;

There is no need to continue checking the rest of the array।

This is an efficient and clear early-return pattern।


Searching for an Index

Sometimes we need the position, not only yes/no।

Example:

static int indexOf(
        int[] numbers,
        int target
) {
    for (
            int i = 0;
            i < numbers.length;
            i++
    ) {
        if (
                numbers[i] == target
        ) {
            return i;
        }
    }

    return -1;
}

Why Return -1?

Valid indexes begin at:

0

So:

-1

can represent:

Not found

This convention is common in many older APIs।

Later, stronger return types can sometimes represent absence more explicitly।


Example

int[] numbers = {
        10,
        20,
        30
};

System.out.println(
        indexOf(
                numbers,
                20
        )
);

Output:

1

Linear Search

The search we just implemented checks elements one by one।

This is called:

Linear Search

We'll study its algorithmic complexity properly in the Algorithms module।

For now:

Check each element until found
or until array ends

Counting Matching Elements

Suppose:

int[] scores = {
        80,
        45,
        90,
        50,
        72
};

We want to count scores:

>= 60

Count Pattern

int passed =
        0;

for (
        int score
        : scores
) {
    if (
            score >= 60
    ) {
        passed++;
    }
}

Result:

3

Counting Method

static int countPassing(
        int[] scores
) {
    int count =
            0;

    for (
            int score
            : scores
    ) {
        if (
                score >= 60
        ) {
            count++;
        }
    }

    return count;
}

Counting Occurrences

Suppose:

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

How many times does 2 appear?

static int countOccurrences(
        int[] values,
        int target
) {
    int count =
            0;

    for (
            int value
            : values
    ) {
        if (
                value == target
        ) {
            count++;
        }
    }

    return count;
}

Result:

3

Filtering Concept

Suppose we want to print only even numbers:

for (
        int number
        : numbers
) {
    if (
            number % 2 == 0
    ) {
        System.out.println(
                number
        );
    }
}

This is conceptually:

Filtering

We inspect every value and keep/process only those matching a condition।

Later, Stream API will allow code such as:

stream.filter(...)

but the underlying idea is the same।


Building a New Filtered Array

Arrays have fixed size, so building a filtered array is less convenient than using collections।

Suppose:

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

We want:

2
4
6

One approach requires two passes।


Pass 1: Count Matches

int evenCount =
        0;

for (
        int number
        : numbers
) {
    if (
            number % 2 == 0
    ) {
        evenCount++;
    }
}

Now we know the result array size।


Pass 2: Copy Matches

int[] evenNumbers =
        new int[evenCount];

int index =
        0;

for (
        int number
        : numbers
) {
    if (
            number % 2 == 0
    ) {
        evenNumbers[index] =
                number;

        index++;
    }
}

This demonstrates one limitation of fixed-size arrays।

Collections will make dynamic filtering easier later।


Traversing Backwards

Indexed loops let us control direction।

for (
        int i =
                numbers.length - 1;
        i >= 0;
        i--
) {
    System.out.println(
            numbers[i]
    );
}

For:

10
20
30

Output:

30
20
10

Reversing an Array In Place

Suppose:

int[] numbers = {
        10,
        20,
        30,
        40
};

We want:

40
30
20
10

We can swap elements from both ends।


Swap Pattern

int temporary =
        numbers[0];

numbers[0] =
        numbers[3];

numbers[3] =
        temporary;

This swaps two values।


General Reverse Algorithm

static void reverse(
        int[] numbers
) {
    int left =
            0;

    int right =
            numbers.length - 1;

    while (
            left < right
    ) {
        int temporary =
                numbers[left];

        numbers[left] =
                numbers[right];

        numbers[right] =
                temporary;

        left++;
        right--;
    }
}

Example

Before:

10 20 30 40 50

Initial:

left  = 0
right = 4

Swap:

10 ↔ 50

Result:

50 20 30 40 10

Then:

left  = 1
right = 3

Swap:

20 ↔ 40

Final:

50 40 30 20 10

Middle element does not need to move।


Why left < right?

When both pointers meet or cross:

All necessary swaps are complete.

Reversing into a New Array

Sometimes we don't want to modify the original।

static int[] reversedCopy(
        int[] numbers
) {
    int[] result =
            new int[
                    numbers.length
            ];

    for (
            int i = 0;
            i < numbers.length;
            i++
    ) {
        result[
                numbers.length
                - 1
                - i
        ] =
                numbers[i];
    }

    return result;
}

Original remains unchanged।


In-Place vs New Array

In-place:

reverse(
        numbers
);

changes the original array।

New-copy approach:

int[] reversed =
        reversedCopy(
                numbers
        );

creates another array।

This distinction appears frequently in software design:

Mutate existing data
vs
Create transformed data

Copying Arrays

Remember:

int[] copy =
        original;

does not copy elements।

It copies the reference।


Manual Copy

int[] copy =
        new int[
                original.length
        ];

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

Now they are separate arrays।


Verify Independence

int[] original = {
        10,
        20,
        30
};

int[] copy =
        new int[
                original.length
        ];

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

copy[0] =
        999;

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

Output:

10

The arrays are independent।


Built-In Copying

Java provides easier options:

Arrays.copyOf(...)

and:

System.arraycopy(...)

We'll study these in the Arrays utility lesson।


Finding the Second Largest? Be Careful

A common beginner exercise asks:

Find second largest element.

But requirements matter।

Example:

5 5 4

Should second largest mean:

5

or:

4

depending on whether duplicates count।

This is a useful engineering lesson:

Algorithms depend on precise requirements.

Do not implement vague requirements blindly।


Neighbor Comparison

Indexes are useful when comparing adjacent elements।

Example:

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

for (
        int i = 0;
        i < numbers.length - 1;
        i++
) {
    System.out.println(
            numbers[i]
            + " -> "
            + numbers[i + 1]
    );
}

Output:

1 -> 3
3 -> 2
2 -> 5

Why length - 1?

Inside the loop we access:

numbers[i + 1]

So i cannot reach the last index।

Otherwise:

last index + 1

would be invalid।


Check if Array Is Sorted

Example:

static boolean isAscending(
        int[] numbers
) {
    for (
            int i = 0;
            i < numbers.length - 1;
            i++
    ) {
        if (
                numbers[i]
                > numbers[i + 1]
        ) {
            return false;
        }
    }

    return true;
}

Example

1 2 3 5

returns:

true

while:

1 4 3 5

returns:

false

This kind of neighbor comparison will become important when studying sorting algorithms।


Finding Duplicate Values — Simple Approach

For small arrays, we can use nested loops:

static boolean hasDuplicate(
        int[] numbers
) {
    for (
            int i = 0;
            i < numbers.length;
            i++
    ) {
        for (
                int j = i + 1;
                j < numbers.length;
                j++
        ) {
            if (
                    numbers[i]
                    == numbers[j]
            ) {
                return true;
            }
        }
    }

    return false;
}

Why Start j at i + 1?

Because we do not need to compare:

An element with itself

and we don't need to repeat comparisons already made।


Example Comparisons

For:

10 20 30

we compare:

10 with 20
10 with 30
20 with 30

not:

10 with 10
20 with 10
30 with 10
...

Nested Loops and Cost

This duplicate algorithm may perform many comparisons as the array grows।

We'll later describe this as approximately:

O(n²)

in the Algorithms module।

For now, just notice:

Nested traversal can become expensive.

Transforming Every Element

Suppose we want a new array where every value is squared।

static int[] squareAll(
        int[] numbers
) {
    int[] result =
            new int[
                    numbers.length
            ];

    for (
            int i = 0;
            i < numbers.length;
            i++
    ) {
        result[i] =
                numbers[i]
                * numbers[i];
    }

    return result;
}

Input:

2 3 4

Output array:

4 9 16

This is conceptually:

Mapping / transformation

Later, streams will call this kind of operation:

map(...)

Traversal Patterns You Should Recognize

Many array problems are combinations of a few recurring patterns।


Pattern 1: Visit Every Element

for (
        int value
        : values
) {
    // process value
}

Pattern 2: Accumulate

int total =
        0;

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

Pattern 3: Count

int count =
        0;

for (
        int value
        : values
) {
    if (
            condition
    ) {
        count++;
    }
}

Pattern 4: Search

for (
        int value
        : values
) {
    if (
            value == target
    ) {
        return true;
    }
}

return false;

Pattern 5: Find Best Value

int max =
        values[0];

for (
        int value
        : values
) {
    if (
            value > max
    ) {
        max =
                value;
    }
}

Pattern 6: Transform

for (
        int i = 0;
        i < values.length;
        i++
) {
    result[i] =
            transform(
                    values[i]
            );
}

Pattern 7: Compare Neighbors

for (
        int i = 0;
        i < values.length - 1;
        i++
) {
    // compare values[i]
    // with values[i + 1]
}

Pattern 8: Two Pointers

int left =
        0;

int right =
        values.length - 1;

while (
        left < right
) {
    // process both ends

    left++;
    right--;
}

These patterns appear far beyond arrays।

You will see them again in:

Collections
Algorithms
Streams
Database processing
Backend logic

Null Array Handling

Suppose:

static int sum(
        int[] numbers
) {
    ...
}

What happens if caller passes:

null

?

Accessing:

numbers.length

would throw:

NullPointerException

A method should have a clear contract।


Option 1: Reject Null Explicitly

static int sum(
        int[] numbers
) {
    if (
            numbers == null
    ) {
        throw new IllegalArgumentException(
                "Numbers are required."
        );
    }

    int total =
            0;

    for (
            int number
            : numbers
    ) {
        total +=
                number;
    }

    return total;
}

Option 2: Define Null as Empty?

You technically could decide:

null means no values

but this often hides mistakes।

In most application code, it is clearer to distinguish:

null

from:

new int[0]

An empty array already represents:

zero elements

well।


Mutation and Method Names

Suppose:

static void reverse(
        int[] numbers
)

modifies the input array।

Its behavior should be clear from documentation/context।

Another design could return a new array:

static int[] reversedCopy(
        int[] numbers
)

The method name communicates:

A copy is created.

Method naming matters when mutation is involved।


Common Beginner Mistake 1: Using Enhanced for to Replace Values

This:

for (
        int number
        : numbers
) {
    number =
            0;
}

does not zero the array।

Use:

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

Common Beginner Mistake 2: Wrong Maximum Initial Value

Avoid:

int max =
        0;

unless the input contract guarantees non-negative values।

Better:

int max =
        numbers[0];

after validating non-empty input।


Common Beginner Mistake 3: Dividing Before Casting

Incorrect for precise average:

double average =
        total
        / numbers.length;

If both operands are integers, integer division happens first।

Use:

double average =
        (double) total
        / numbers.length;

Common Beginner Mistake 4: Accessing First Element of Empty Array

This fails:

int[] numbers =
        new int[0];

int max =
        numbers[0];

Operations requiring at least one element should validate that requirement।


Common Beginner Mistake 5: Returning Too Late During Search

This is wrong:

static boolean contains(
        int[] numbers,
        int target
) {
    for (
            int number
            : numbers
    ) {
        if (
                number == target
        ) {
            return true;
        } else {
            return false;
        }
    }

    return false;
}

Why?

It checks only the first element।

If the first element doesn't match, it immediately returns false


Correct Search

static boolean contains(
        int[] numbers,
        int target
) {
    for (
            int number
            : numbers
    ) {
        if (
                number == target
        ) {
            return true;
        }
    }

    return false;
}

Only return false after checking every element।


Common Beginner Mistake 6: Modifying While Assuming a Copy

If:

reverse(
        numbers
);

modifies the supplied array, caller data changes।

Remember:

Array parameters point to the same mutable array object.

If you need preservation, create a copy।


Practical Example: Score Analysis

Let's combine several traversal patterns।

public class Main {

    public static void main(String[] args) {
        int[] scores = {
                82,
                91,
                45,
                76,
                88
        };

        System.out.println(
                "Total: "
                + sum(
                        scores
                )
        );

        System.out.println(
                "Average: "
                + average(
                        scores
                )
        );

        System.out.println(
                "Highest: "
                + max(
                        scores
                )
        );

        System.out.println(
                "Passing: "
                + countPassing(
                        scores
                )
        );
    }

    static int sum(
            int[] scores
    ) {
        int total =
                0;

        for (
                int score
                : scores
        ) {
            total +=
                    score;
        }

        return total;
    }

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

        return (double) sum(
                scores
        ) / scores.length;
    }

    static int max(
            int[] scores
    ) {
        if (
                scores.length == 0
        ) {
            throw new IllegalArgumentException(
                    "Scores cannot be empty."
            );
        }

        int max =
                scores[0];

        for (
                int i = 1;
                i < scores.length;
                i++
        ) {
            if (
                    scores[i] > max
            ) {
                max =
                        scores[i];
            }
        }

        return max;
    }

    static int countPassing(
            int[] scores
    ) {
        int count =
                0;

        for (
                int score
                : scores
        ) {
            if (
                    score >= 60
            ) {
                count++;
            }
        }

        return count;
    }
}

This program demonstrates:

Traversal
Accumulation
Average
Maximum
Counting
Method reuse
Input validation

Practice 1: Sum

Write:

static int sum(
        int[] numbers
)

without using any utility methods।


Solution

static int sum(
        int[] numbers
) {
    int total =
            0;

    for (
            int number
            : numbers
    ) {
        total +=
                number;
    }

    return total;
}

Practice 2: Count Even Numbers

Write:

static int countEven(
        int[] numbers
)

Solution

static int countEven(
        int[] numbers
) {
    int count =
            0;

    for (
            int number
            : numbers
    ) {
        if (
                number % 2 == 0
        ) {
            count++;
        }
    }

    return count;
}

Practice 3: Find Minimum

Write:

static int min(
        int[] numbers
)

Assume empty arrays should be rejected।


Solution

static int min(
        int[] numbers
) {
    if (
            numbers.length == 0
    ) {
        throw new IllegalArgumentException(
                "Array cannot be empty."
        );
    }

    int min =
            numbers[0];

    for (
            int i = 1;
            i < numbers.length;
            i++
    ) {
        if (
                numbers[i] < min
        ) {
            min =
                    numbers[i];
        }
    }

    return min;
}

Practice 4: Search

Write:

static boolean contains(
        int[] numbers,
        int target
)

Solution

static boolean contains(
        int[] numbers,
        int target
) {
    for (
            int number
            : numbers
    ) {
        if (
                number == target
        ) {
            return true;
        }
    }

    return false;
}

Practice 5: Find Index

Write:

static int indexOf(
        String[] values,
        String target
)

Return:

-1

when not found।


Solution

static int indexOf(
        String[] values,
        String target
) {
    for (
            int i = 0;
            i < values.length;
            i++
    ) {
        if (
                values[i].equals(
                        target
                )
        ) {
            return i;
        }
    }

    return -1;
}

Practice 6: Double All Values

Given:

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

modify it into:

2
4
6

Solution

for (
        int i = 0;
        i < numbers.length;
        i++
) {
    numbers[i] *=
            2;
}

Practice 7: Reverse

Implement:

static void reverse(
        String[] values
)

that reverses the array in place।


Solution

static void reverse(
        String[] values
) {
    int left =
            0;

    int right =
            values.length - 1;

    while (
            left < right
    ) {
        String temporary =
                values[left];

        values[left] =
                values[right];

        values[right] =
                temporary;

        left++;
        right--;
    }
}

Practice 8: Check Sorted Order

Write:

static boolean isAscending(
        int[] numbers
)

Solution

static boolean isAscending(
        int[] numbers
) {
    for (
            int i = 0;
            i < numbers.length - 1;
            i++
    ) {
        if (
                numbers[i]
                > numbers[i + 1]
        ) {
            return false;
        }
    }

    return true;
}

Practice 9: Predict the Output

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

for (
        int number
        : numbers
) {
    number =
            100;
}

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

Answer

1

The enhanced-loop variable was changed, not the array element।


Practice 10: Predict the Output

int[] numbers = {
        5,
        10,
        15
};

int total =
        0;

for (
        int number
        : numbers
) {
    total +=
            number;
}

System.out.println(
        total
);

Answer

30

True or False

  1. An indexed loop gives access to array positions.
  2. Enhanced for directly provides indexes.
  3. Enhanced for is convenient for reading every value.
  4. Reassigning a primitive enhanced-loop variable changes the original array.
  5. i < array.length is a common safe traversal condition.
  6. Maximum should always start at 0.
  7. Searching can return early when a target is found.
  8. A fixed-size array makes dynamic filtering slightly inconvenient.
  9. array2 = array1 creates an independent copy.
  10. Reversing in place modifies the original array.
  11. Two-pointer traversal can be useful for reversing.
  12. Neighbor comparisons often require stopping before the final index.

Answers

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

Knowledge Check

Question 1

What is array traversal?

Question 2

When should you prefer an indexed for loop?

Question 3

When is an enhanced for loop convenient?

Question 4

Why doesn't assigning to a primitive enhanced-loop variable modify the array?

Question 5

What is an accumulator?

Question 6

Why should maximum/minimum usually start from a real array element?

Question 7

Why should search return false only after the traversal completes?

Question 8

Why can filtering into another array require two passes?

Question 9

What is an in-place operation?

Question 10

What is the difference between copying an array reference and copying array elements?

Question 11

What is the two-pointer pattern?

Question 12

Why are recurring traversal patterns useful to recognize?


Knowledge Check Answers

Answer 1

Array traversal means visiting array elements systematically so they can be read, compared, transformed, counted, searched, or otherwise processed।

Answer 2

When you need the index, need to modify array positions, compare neighbors, traverse backwards, or control positions precisely।

Answer 3

When you simply need to process each value and do not need its index।

Answer 4

The loop variable receives a copy of the primitive element value, so reassigning that local variable does not replace the element stored in the array।

Answer 5

An accumulator is a variable that starts with an initial value and collects a result progressively during traversal, such as a sum।

Answer 6

Because an arbitrary initial value such as 0 may not belong to the data and can produce incorrect results, especially with negative values।

Answer 7

Because a target may appear later in the array; returning false after the first non-match would stop the search prematurely।

Answer 8

Because an array needs its size at creation time, so we may first need to count how many elements match before allocating the result array।

Answer 9

An in-place operation changes the existing array rather than creating a separate transformed array।

Answer 10

Copying the reference makes two variables point to the same array; copying elements creates a separate array object containing corresponding values।

Answer 11

It uses two positions, often one from each end, and moves them toward each other while processing or swapping values।

Answer 12

Because many apparently different problems are built from the same patterns such as accumulation, search, counting, transformation, neighbor comparison, and two-pointer traversal।


Lesson Summary

এই lesson-এ আমরা arrays শুধু store করা নয়, practicalভাবে process করা শিখেছি।

We learned:

  • Array traversal means systematically processing elements
  • Indexed for loops provide both position and value
  • Enhanced for loops simplify value-only traversal
  • while can also traverse arrays
  • Indexed loops are needed for direct element replacement
  • Enhanced-loop primitive variables do not replace array elements
  • Accumulator patterns calculate totals and other aggregate values
  • Average calculation requires careful numeric division
  • Minimum and maximum should usually initialize from real input data
  • Linear search checks values one by one
  • Early return simplifies successful search
  • Counting is another common traversal pattern
  • Filtering fixed-size arrays may require extra work
  • Arrays can be traversed backwards
  • Two-pointer logic can reverse arrays efficiently
  • In-place operations mutate the original array
  • New-array transformations preserve the original
  • Copying a reference is different from copying elements
  • Neighbor comparisons support sorted-order checks and later sorting algorithms
  • Nested traversal can solve duplicate detection but may become expensive
  • Common traversal patterns appear repeatedly throughout programming

The most important patterns to remember are:

Visit
Accumulate
Count
Search
Find min/max
Transform
Compare neighbors
Two pointers

Once these patterns become familiar, many array problems become much easier to reason about।


Next Lesson

পরবর্তী lesson:

Two-Dimensional and Multidimensional Arrays

আমরা শিখব:

  • What a 2D array represents
  • Rows and columns
  • Creating 2D arrays
  • Accessing cells
  • Nested traversal
  • Initializing matrix-like data
  • Jagged arrays
  • Row lengths
  • Passing 2D arrays to methods
  • Common matrix operations
  • Multidimensional arrays beyond 2D