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_INFINITYfor adouble,Integer.MIN_VALUEfor anint) so the very first real value always replaces it. NotDouble.MIN_VALUE— that's the smallest positivedouble, 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
ifinside 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() < psimulates an event with probabilityp.
Derived from csawesome-2026: unit-2-selection-and-iteration/2.09-implementing-selection-and-iteration-algorithms.md (CSA 2.9)