Implementing Selection and Iteration Algorithms

A handful of loop-and-selection patterns come up constantly. Once you recognize them, you'll see the same shape everywhere.

The examples below loop over an existing collection (visionLatencies, sensors) with an enhanced for — building your own comes in Ch.9. Read for (double sample : visionLatencies) as "for each sample in visionLatencies": the loop variable takes each value in turn, first to last, with no index to manage (Lesson 9.4 covers it fully). For now, focus on the accumulator/selection shape itself; it applies the same way once you get there.

The Accumulator Pattern

Build up a running total across a loop: initialize before the loop, update inside it, use the result after.

double sum = 0;
for (double sample : visionLatencies)
{
    sum += sample; // accumulate
}
double average = sum / visionLatencies.size();

Min/Max with an if Inside a Loop

Track the smallest or largest value seen so far by pairing an accumulator with an if inside the loop:

double max = Double.NEGATIVE_INFINITY; // below every real number
for (double sample : visionLatencies)
{
    if (sample > max)
    {
        max = sample; // running max
    }
}

Double.NEGATIVE_INFINITY is a special double value smaller than every real number, so the first sample always replaces it. (Double is Java's wrapper class for double; its constants and the other wrapper classes come in Lesson 9.2.) Watch out for the similar-looking Double.MIN_VALUE: despite the name, it's the smallest positive double (about 4.9E-324), so a max seeded with it stays wrong whenever every sample is zero or negative.

Frequency Counting

Count how many values in a sequence meet some criterion, using a counter incremented inside a conditional:

int faultyCount = 0;
for (Sensor sensor : sensors)
{
    if (sensor.isFaulty())
    {
        faultyCount++;
    }
}

Simulating Probability with Math.random()

Math.random() < p is true with probability p — a real way to simulate an event that happens some percentage of the time (useful for testing code against randomized simulated sensor noise, for instance):

if (Math.random() < 0.1) // roughly 10% of the time
{
    simulateSensorGlitch();
}

Common Pitfalls

  • Initializing an accumulator with the wrong starting value. A sum starts at 0; a max should start below every possible value (Double.NEGATIVE_INFINITY for a double, Integer.MIN_VALUE for an int) so the very first real value always replaces it. Not Double.MIN_VALUE — that's the smallest positive double, not the most negative one.
  • Putting the accumulator update outside the loop. It has to be inside the loop body to actually accumulate across every iteration.

Key Takeaways

  • The accumulator pattern: initialize before the loop, update inside it, use the result after.
  • Min/max tracking pairs an accumulator with an if inside the loop, comparing each new value against the best one seen so far.
  • Frequency counting increments a counter inside a conditional, once per matching iteration.
  • Math.random() < p simulates an event with probability p.

Derived from csawesome-2026: unit-2-selection-and-iteration/2.09-implementing-selection-and-iteration-algorithms.md (CSA 2.9)