Course outline · 0% complete

0/29 lessons0%

Course overview →

Loops and arrays

lesson 3-3 · ~8 min · 9/29

while and for

A loop is how one line of logic handles a million rows: apply the tax rule to every order, check every password attempt, sum every sensor reading. Without loops you would copy the same statement once per item, which is exactly what early programmers did.

while is Python's while with parentheses and braces. The classic for packs setup, condition, and step into one line:

for (int i = 0; i < 5; i++) {
  System.out.println(i);
}

Read it as three parts: start i at 0, keep looping while i < 5, add 1 after each pass. It prints 0 through 4, exactly like Python's for i in range(5).

The counter i is declared inside the parentheses, so it exists only for the duration of the loop and the name is free to reuse in the next one. break and continue behave the same as in Python.

Arrays

An array is Java's fixed-size list. Its type is the element type followed by []:

int[] scores = {90, 72, 88};
scores[0]        // 90
scores.length    // 3, a field with no parentheses
scores[1] = 75;  // arrays are mutable

Unlike a Python list, an array cannot grow or shrink, and every element has the same declared type. Adding a fourth score means creating a new array, which is why real code reaches for ArrayList once the size is not known up front.

To visit each element, Java has the enhanced for loop, its version of for x in list:

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

Read : as "in". You get each element in order without managing an index, which removes the boundary mistake described further down. Use the classic for when you actually need the index, and the enhanced form otherwise.

90728864[0][1][2][3]s
The enhanced for loop visits each array slot in order. The variable s takes the value of one element per pass.

A countdown and a sum

A classic for counting down, then an enhanced for adding up an array.

public class Main {
  public static void main(String[] args) {
    for (int i = 3; i >= 1; i--) {
      System.out.println(i);
    }
    int[] scores = {90, 72, 88, 64};
    int total = 0;
    for (int s : scores) {
      total += s;
    }
    System.out.println("total: " + total);
    System.out.println("count: " + scores.length);
  }
}

Output

3
2
1
total: 314
count: 4

The countdown starts high and steps with i--, which shows that the three parts of a classic for are ordinary code rather than a fixed formula.

The sum is the accumulator pattern: a variable declared before the loop, updated once per element, and read after the loop ends. Declaring total inside the loop would reset it every pass and print 64.

Off by one, the classic loop bug

Array indexes run from 0 to length - 1. Asking for scores[3] on a 3-element array throws an ArrayIndexOutOfBoundsException at runtime, and the compiler cannot catch it, because the index might be computed from data it cannot predict.

This is why the classic loop idiom is always i < scores.length and never i <= scores.length:

ConditionPassesResult
i < scores.lengthindexes 0, 1, 2correct
i <= scores.lengthindexes 0, 1, 2, 3throws on the last pass

The <= version runs one extra pass and dies on it. When a loop crashes, check the boundary first, since it is the most common loop bug in any language.

The enhanced for sidesteps the problem entirely, because there is no index to get wrong. That is the strongest argument for using it whenever the index itself is not needed.

length and length()

An array called data reports its size as data.length, while a String called s reports its size as s.length().

This is a classic Java inconsistency. Arrays expose length as a field, with no parentheses, and Strings expose length() as a method, with parentheses.

ValueSize expression
int[] datadata.length
String ss.length()

Mixing them up is a compile error rather than a silent bug, so javac corrects you immediately and the mistake costs seconds rather than a debugging session. The reason for the split is historical: an array is a built-in language construct while a String is an ordinary object with methods.

Summing evens, then finding a maximum

Two loop shapes in one program: a classic for with a condition inside, and an enhanced for tracking a running best.

public class Main {
  public static void main(String[] args) {
    int sum = 0;
    for (int i = 1; i <= 10; i++) {
      if (i % 2 == 0) {
        sum += i;
      }
    }
    System.out.println("even sum: " + sum);

    double[] prices = {4.0, 9.5, 7.25, 3.1};
    double max = prices[0];
    for (double p : prices) {
      if (p > max) {
        max = p;
      }
    }
    System.out.println("max: " + max);
  }
}

Output

even sum: 30
max: 9.5

The first loop counts every number from 1 to 10 and the if decides which ones contribute, so 2 plus 4 plus 6 plus 8 plus 10 gives 30. Here i <= 10 is correct because these are values rather than indexes.

The second loop is the running maximum pattern. max starts at the first element and is replaced whenever something bigger appears, which is why the enhanced for visiting prices[0] again is harmless.

The running maximum on its own

The same sweep applied to temperatures, starting from the first element rather than from zero.

public class Main {
  public static void main(String[] args) {
    int[] temps = {68, 74, 61, 79, 72};
    int max = temps[0];
    for (int t : temps) {
      if (t > max) {
        max = t;
      }
    }
    System.out.println("max: " + max);
  }
}

Output

max: 79

for (int t : temps) visits every element in order, and the single if inside promotes t to the new best whenever it is larger. Nothing needs to remember where the maximum was found.

Starting max at temps[0] rather than at 0 is the detail that makes this correct in general. An array of below-zero temperatures would report a maximum of 0 under the other version, which is a value that never appeared in the data.