JAVA • COLLECTIONS AND STRINGS

Array Iteration & Aggregates — Iterate through arrays and compute aggregates

Learn to traverse arrays with loops and compute sums, averages, min, max, and counts in Java.

Historical Context & Motivation

Long before modern programming languages existed, mathematicians and scientists needed ways to process collections of numbers — computing totals, finding extremes, and summarizing large data sets. When early computers emerged in the 1940s and 1950s, one of the first problems programmers tackled was how to store and process sequences of values efficiently. The concept of an array — a fixed-size block of memory holding elements of the same type — became the foundational data structure for solving these problems.

As programming languages evolved, the idea of iteration — stepping through each element of a collection one by one — became central to how we work with data. Whether you are calculating a student's grade average, finding the highest score in a game, or counting how many sensor readings exceed a threshold, iteration over arrays is the tool that makes it possible. Java, released in 1995, carried these ideas forward with clean syntax and strong type safety.

1945
Arrays in Early Computing
Konrad Zuse's Plankalkül language introduced the idea of indexed storage — the predecessor to arrays — enabling repeated operations on sequences of numbers.
1957
FORTRAN Formalizes Arrays
IBM's FORTRAN became the first widely used language to support arrays and DO loops, allowing scientists to iterate through data sets systematically.
1972
C Popularizes Array Indexing
The C language introduced zero-based array indexing (starting from index 0), a convention that Java would later adopt directly.
1995
Java Launches with Built-in Arrays
Java included arrays as first-class objects with bounds checking and a .length property, making iteration safer and more predictable than in C.
2004
Enhanced for Loop (for-each)
Java 5 introduced the enhanced for loop, simplifying array iteration by eliminating the need for manual index management.

The core question this lesson addresses is: given a collection of values stored in an array, how do we visit each element and compute useful summary values — called aggregates — such as sums, averages, minimums, maximums, and counts? Mastering this pattern is essential because nearly every real-world program processes collections of data.

Core Principles & Definitions

Before we write any code, let's establish the key ideas behind array iteration and aggregation. An aggregate is a single value computed from many values — think of it as a summary statistic. The process of visiting each element in an array is called traversal, and we accomplish it by using loops. There are two main loop styles in Java for array traversal: the traditional for loop and the enhanced for-each loop.

1

Array Traversal

The process of visiting every element in an array exactly once, typically using a loop that starts at index 0 and ends at array.length − 1.
2

Accumulator Pattern

A variable initialized before the loop that gets updated with each iteration. For a sum, the accumulator starts at 0 and adds each element. For a product, it starts at 1 and multiplies.
3

Aggregate Functions

Common aggregates include sum, average, minimum, maximum, and count. Each uses the accumulator pattern with a different update rule inside the loop body.
4

Index vs. Value Access

A traditional for loop provides the index (position) and value. A for-each loop provides only the value. Choose based on whether you need the index for your computation.
5

Bounds Safety

Java throws an ArrayIndexOutOfBoundsException if you access an index outside 0 to length − 1. Always use < array.length (not <=) as your loop condition.
✦ KEY TAKEAWAY
Think of an array like a row of mailboxes in an apartment building. Each mailbox has a number (the index) and contains a letter (the value). Iteration is like a mail carrier walking from the first mailbox to the last, checking each one. An aggregate is the summary the carrier gives at the end — "there were 12 letters total" (sum) or "the heaviest package was 3 pounds" (max).

Visual Explanation — How Array Iteration Works

The diagram below shows how a for loop traverses an integer array to compute a running sum. Notice how the index variable i advances from 0 to 4, and the accumulator variable sum grows as each element is added.

Each iteration reads one element from the array and adds it to the running sum accumulator. After all five elements are processed, the total is 100.

In the diagram above, each row represents one pass through the loop body. The index i moves from 0 to 4, and the accumulator sum grows by the value at that index. This is the accumulator pattern in action. Every aggregate — sum, count, min, max — uses a variation of this same idea: initialize a variable, loop through the array, and update the variable at each step.

How It Works — Loop Structures & Code Patterns

The Traditional for Loop

The traditional for loop gives you full control over the index variable. Its structure has three parts separated by semicolons: initialization (run once before the loop starts), condition (checked before each iteration), and update (run after each iteration). The standard idiom for traversing an array looks like this:

TRADITIONAL FOR LOOP
for (int i = 0; i < arr.length; i++) { /* use arr[i] */ }
i = index variable, starts at 0. arr.length = number of elements. arr[i] = element at position i.

The Enhanced for-each Loop

When you don't need the index — just the values — Java's enhanced for loop (also called the for-each loop) is cleaner. It automatically iterates through every element without requiring you to manage an index counter.

ENHANCED FOR-EACH LOOP
for (int value : arr) { /* use value */ }
value = a copy of each element in arr, visited in order from index 0 to length − 1.

Common Aggregate Patterns

SUM
int sum = 0; for (int v : arr) { sum += v; }
Accumulator starts at 0. Each element is added. After the loop, sum holds the total.
AVERAGE
double avg = (double) sum / arr.length;
Compute the sum first, then divide by the number of elements. The cast to double avoids integer division truncation.
MIN / MAX
int min = arr[0]; for (int v : arr) { if (v < min) min = v; }
Initialize to the first element (not to 0 or Integer.MAX_VALUE for beginners). Then compare each element and update if smaller. Replace < with > for maximum.
⚠️ Why initialize min/max to arr[0]?
If you initialize min to 0 and all array values are positive, you'll get 0 as the minimum — which isn't even in the array! Starting with arr[0] guarantees your initial value is a real element, so comparisons work correctly for any set of values.

Detailed Breakdown of Aggregate Operations

Each aggregate operation follows the same three-phase structure: initialize an accumulator variable, iterate through the array updating the accumulator, and report the result after the loop. What changes between different aggregates is the initialization value and the update rule. The diagram below summarizes the five most common aggregates side by side.

All five aggregate operations follow the same three-phase pattern: Initialize → Iterate → Report. The only differences are the starting value and the update logic inside the loop.
Summary of common aggregate operations
AggregateInit ValueUpdate RuleResult Type
Sum0sum += arr[i]int or double
Average0 (sum first)sum += arr[i], then dividedouble
Minimumarr[0]if (arr[i] < min) min = arr[i]Same as array type
Maximumarr[0]if (arr[i] > max) max = arr[i]Same as array type
Count0if (condition) count++int

Worked Example — Student Grade Analysis

Let's walk through a complete example that computes multiple aggregates from a single array. Suppose you have an array of test scores and you need to find the sum, average, highest score, lowest score, and how many students scored above 80.

Grade Analysis: Computing Five Aggregates
1
Step 1 — Declare the ArrayStart by declaring and initializing the array of test scores: int[] grades = {72, 95, 88, 61, 84, 77, 93}; This creates an array with 7 elements at indices 0 through 6.
Array length: grades.length = 7
2
Step 2 — Initialize AccumulatorsWe need five accumulator variables. For sum and count, we initialize to 0. For min and max, we initialize to the first element of the array: int sum = 0; int min = grades[0]; int max = grades[0]; int count = 0; Notice that we don't need a separate accumulator for average — we'll compute it from the sum after the loop.
sum=0, min=72, max=72, count=0
3
Step 3 — Write the LoopWe can compute all aggregates in a single pass through the array using one for-each loop: for (int g : grades) { sum += g; if (g < min) min = g; if (g > max) max = g; if (g > 80) count++; } Each element is processed once, and all four accumulators are updated in the same loop body.
4
Step 4 — Trace Through the LoopLet's trace iteration by iteration. After g=72: sum=72, min=72, max=72, count=0. After g=95: sum=167, min=72, max=95, count=1. After g=88: sum=255, min=72, max=95, count=2. After g=61: sum=316, min=61, max=95, count=2. After g=84: sum=400, min=61, max=95, count=3. After g=77: sum=477, min=61, max=95, count=3. After g=93: sum=570, min=61, max=95, count=4.
sum=570, min=61, max=95, count=4
5
Step 5 — Compute the AverageAfter the loop, compute the average by casting the sum to double before dividing: double avg = (double) sum / grades.length; This gives us 570.0 ÷ 7 = 81.43 (rounded to two decimal places). Without the cast, Java would perform integer division and give us 81 instead of 81.43.
Sum=570, Avg≈81.43, Min=61, Max=95, Above-80 Count=4
💡 Efficiency Tip
Notice that we computed all five aggregates in a single loop. You could write five separate loops — one for each aggregate — and get the same answers, but combining them into one loop means the array is only traversed once. This is both simpler to read and more efficient.

Traditional for vs. Enhanced for-each

Both loop styles can accomplish array iteration, but they have different strengths. Choosing the right one depends on what your code needs to do. The table below breaks down the key differences.

Comparison of Java loop styles for array iteration
FeatureTraditional for LoopEnhanced for-each Loop
Syntaxfor (int i = 0; i < arr.length; i++)for (int v : arr)
Index available?Yes — via iNo — only the value
Can modify elements?Yes — arr[i] = newValNo — v is a copy
Partial traversal?Yes — change start/end/stepNo — always visits every element
Risk of off-by-one?Yes — using <= instead of <No — loop manages bounds automatically
Best for aggregates?When you need the index (e.g., index of max)When you only need values (sum, avg, min, max)
✦ KEY TAKEAWAY
Think of the traditional for loop like driving a car with a manual transmission — you have full control over every gear shift (index), but it requires more attention. The for-each loop is like an automatic transmission — simpler and less error-prone for the common case. For most aggregate computations, the for-each loop is the better choice because you just need the values, not the positions.

Connection to Advanced Java Collections

The iteration and aggregation patterns you've learned here apply far beyond basic arrays. Java's Collections Framework provides dynamic data structures like ArrayList that grow and shrink as needed. The Stream API, introduced in Java 8, allows you to express aggregates in a more declarative style. Understanding the fundamental loop-based approach gives you the foundation to appreciate these more powerful tools later.

Arrays vs. Advanced Collections
FeatureArray + Loop (This Lesson)ArrayList + Stream (Advanced)
SizeFixed at creation timeDynamic — grows automatically
Sumfor (int v : arr) sum += v;list.stream().mapToInt(x->x).sum()
MinManual loop with if-statementCollections.min(list)
Count with conditionLoop with if and counterlist.stream().filter(x->x>80).count()
When to learnNow — foundationalAfter mastering arrays and basic OOP

Even though tools like Streams can compute aggregates in a single line, they work by doing the same iteration under the hood. Mastering the explicit loop-based approach ensures you understand exactly what the computer is doing at each step — which is critical for debugging, performance reasoning, and writing correct code in any language.

Practice Problems

PROBLEM 1 — CONCEPTUAL
Explain why we initialize the min variable to arr[0] instead of 0 when finding the minimum value in an array. Give a specific example where initializing to 0 would produce a wrong answer.
PROBLEM 2 — BASIC CALCULATION
Given int[] data = {14, 7, 23, 11, 19};, trace through a for-each loop to compute the sum. Show the value of sum after each iteration, and then calculate the average.
PROBLEM 3 — INTERMEDIATE
Write a Java method called countAboveAverage that takes an int[] as a parameter and returns the number of elements that are strictly greater than the array's average. Hint: you will need two passes through the array.
PROBLEM 4 — APPLIED
A weather station records daily high temperatures (in °F) for a week: int[] temps = {68, 73, 81, 79, 85, 90, 72}; Write Java code that computes: (a) the average temperature, (b) the hottest day's temperature, (c) the index of the hottest day (0=Monday, 6=Sunday), and (d) how many days exceeded 80°F.
PROBLEM 5 — CRITICAL THINKING
Consider an array that might be empty (length 0). Which aggregate operations would cause an error or produce a meaningless result if the array is empty? For each problematic aggregate, explain what goes wrong and propose a solution using a guard clause (an if-statement before the loop).

Lesson Summary

In this lesson, you learned how to traverse arrays using both the traditional for loop (which gives you index access) and the enhanced for-each loop (which simplifies value-only iteration). The core pattern behind all aggregate computations is the accumulator pattern: initialize a variable before the loop, update it inside the loop, and use it after the loop.

You applied this pattern to five common aggregates: sum (init to 0, add each element), average (sum divided by length, using a double cast), minimum and maximum (init to arr[0], compare with < or >), and conditional count (init to 0, increment when a condition is met). These patterns form the building blocks for data processing in every Java program you'll ever write, and they translate directly to more advanced tools like ArrayList and the Stream API.

Varsity Tutors • Java • Array Iteration & Aggregates