Selection and Iteration

The biggest unit on the exam. Programs make decisions with booleans and if-statements, and repeat work with loops. Master these and you've mastered a quarter of the test.

2.1 Boolean Expressions

A boolean expression evaluates to true or false. The most common boolean expressions use relational operators:

OperatorMeaningExample (x = 5)Result
==equal tox == 5true
!=not equal tox != 3true
>greater thanx > 5false
<less thanx < 10true
>=greater or equalx >= 5true
<=less or equalx <= 4false
🚨 = vs ==

= is assignment. == is comparison. if (x = 5) is a compile error in Java because x = 5 isn't a boolean.

✏️ Your turn — boolean variables

Given int age = 17;:

  1. Declare a boolean canVote that's true when age >= 18
  2. Declare a boolean isTeen that's true when age is between 13 and 19 inclusive

Print both, prefixed with canVote: and isTeen: .

Show solution
public class Main {
    public static void main(String[] args) {
        int age = 17;
        boolean canVote = age >= 18;
        boolean isTeen = age >= 13 && age <= 19;
        System.out.println("canVote: " + canVote);
        System.out.println("isTeen: " + isTeen);
    }
}

Comparing objects vs primitives

For primitives (int, double, boolean), == compares values. For objects, == compares references — whether two variables point at the same object. Use .equals() to compare contents.

✏️ Your turn — == vs .equals()

Build two separate String objects using new String("hello") (this forces two different objects). Print a == b and a.equals(b). Predict which is true and which is false before running.

Show solution
public class Main {
    public static void main(String[] args) {
        String a = new String("hello");
        String b = new String("hello");
        System.out.println(a == b);        // false
        System.out.println(a.equals(b));   // true
    }
}

2.2 if, if-else, and else if

Basic if

if (condition) {
    // runs when condition is true
}

if-else — exactly one branch runs

if (condition) { ... }
else          { ... }

else if chain — first true wins

Java tests conditions in order. As soon as one is true, that branch runs and the entire rest of the chain is skipped.

✏️ Your turn — grading chain

Given int score = 85;, write an if/else-if chain that assigns a String grade using the standard cutoffs:

  • 90+ → "A"
  • 80+ → "B"
  • 70+ → "C"
  • 60+ → "D"
  • otherwise → "F"

Print Grade: followed by the result. (Expected: Grade: B.)

Show solution
public class Main {
    public static void main(String[] args) {
        int score = 85;
        String grade;
        if      (score >= 90) grade = "A";
        else if (score >= 80) grade = "B";
        else if (score >= 70) grade = "C";
        else if (score >= 60) grade = "D";
        else                  grade = "F";
        System.out.println("Grade: " + grade);
    }
}
🚨 Order matters in a chain

If you wrote if (score >= 60) first, every score from 60+ would get a D. The chain only works because each branch implicitly assumes the previous one was false.

Chain vs. independent ifs

// CHAIN — only ONE branch runs
if      (x > 0)  { ... }
else if (x > 10) { ... }   // unreachable! x > 10 implies x > 0

// INDEPENDENT — multiple can run
if (x > 0)  { ... }
if (x > 10) { ... }        // both run when x is 11+

2.3 Compound Boolean Expressions

Combine booleans with logical operators:

  • &&AND: true only if both sides are true
  • ||OR: true if at least one side is true
  • !NOT: flips true/false

Truth tables

ABA && BA || B!A
TTTTF
TFFTF
FTFTT
FFFFT

Short-circuit evaluation — CRUCIAL

Java evaluates left to right and stops as soon as the answer is known.

  • false && anything → false, right side never evaluated
  • true || anything → true, right side never evaluated
💡 Short-circuit saves your code

This is why if (s != null && s.length() > 0) works — if s is null, the second part never runs, so no NullPointerException.

✏️ Your turn — short-circuit in action

With int x = 0;, write an if that checks x != 0 && 10 / x > 1. Note that you'd get a division-by-zero crash if Java evaluated both sides, but short-circuit saves you. After the if, print Survived!.

Then write a second if using || that checks true || (1 / 0 == 0) — again, short-circuit prevents the crash. Print Short-circuit on || too.

Show solution
public class Main {
    public static void main(String[] args) {
        int x = 0;
        if (x != 0 && 10 / x > 1) {
            System.out.println("won't print");
        }
        System.out.println("Survived!");

        if (true || (1 / 0 == 0)) {
            System.out.println("Short-circuit on || too");
        }
    }
}

2.4 Equivalent Expressions & De Morgan's Laws

📘 De Morgan's Laws

!(A && B) is equivalent to !A || !B

!(A || B) is equivalent to !A && !B

In plain English: distribute the ! across both operands and flip the connective (AND ↔ OR).

Negating relational operators

  • !(x > 5)x <= 5
  • !(x == 5)x != 5
  • !(x >= 5)x < 5
✏️ Your turn — De Morgan

With int a = 7, b = 3;:

  1. Declare boolean p equal to !(a > 5 && b < 5)
  2. Declare boolean q equal to its De Morgan equivalent: a <= 5 || b >= 5
  3. Print p + " " + q — both should be false.
Show solution
public class Main {
    public static void main(String[] args) {
        int a = 7, b = 3;
        boolean p = !(a > 5 && b < 5);
        boolean q = (a <= 5 || b >= 5);
        System.out.println(p + " " + q);  // false false
    }
}
Which is equivalent to !(a >= 5 && b < 10)?
A a < 5 && b >= 10
B a < 5 || b >= 10
C a <= 5 || b > 10
D a >= 5 || b < 10

2.5 while Loops

A while loop repeats a block as long as a condition is true. Condition is checked before each iteration.

while (condition) {
    // body
}

The three parts of every loop

  1. Initialization — set up the loop variable before the loop
  2. Condition — when to keep looping
  3. Update — change the variable inside the loop
✏️ Your turn — first while loop

Use a while loop to print i = 0 through i = 4 on separate lines. After the loop, print After loop: i = 5 (notice i is still in scope because you declared it outside).

Show solution
public class Main {
    public static void main(String[] args) {
        int i = 0;
        while (i < 5) {
            System.out.println("i = " + i);
            i++;
        }
        System.out.println("After loop: i = " + i);  // 5
    }
}
🚨 Infinite loops

Forget the update? Loop runs forever. Always check your loop variable is changing toward the exit condition.

Sentinel pattern — loop until a flag value

int n = 1, sum = 0;
while (n != 0) {
    sum += n;
    // ... fetch next n from somewhere
}

2.6 for Loops

A for loop packages initialization, condition, and update into one line. Use it when you know how many times to loop.

for (initialization; condition; update) {
    // body
}
✏️ Your turn — two for loops

Using System.out.print (no newline) and a single println() in between:

  1. Print 1 2 3 4 5 6 7 8 9 10 on one line
  2. Then print the even numbers from 20 down to 0, space-separated: 20 18 16 14 12 10 8 6 4 2 0

Use two for loops — one counting up, one counting down by 2.

Show solution
public class Main {
    public static void main(String[] args) {
        for (int i = 1; i <= 10; i++) {
            System.out.print(i + " ");
        }
        System.out.println();

        for (int i = 20; i >= 0; i -= 2) {
            System.out.print(i + " ");
        }
    }
}

for vs while — equivalent

// for loop
for (int i = 0; i < 10; i++) { ... }

// equivalent while loop
int i = 0;
while (i < 10) {
    ...
    i++;
}
📘 Scope of loop variable

A variable declared in the for header only exists inside the loop. If you need it afterward, declare it before the loop and use a while.

2.7 Developing Algorithms with Strings

String-processing problems are AP exam favorites. Most boil down to: loop over each character with index i and check or build with substring(i, i+1).

Classic: count occurrences of a letter

✏️ Your turn — countLetter

Write a static method countLetter(String s, String target) that returns the number of times target (a 1-character string) appears in s. Use substring(i, i+1) and .equals(target).

Test from main with:

  • countLetter("mississippi", "s") → 4
  • countLetter("mississippi", "i") → 4
  • countLetter("banana", "a") → 3
Show solution
public static int countLetter(String s, String target) {
    int count = 0;
    for (int i = 0; i < s.length(); i++) {
        if (s.substring(i, i + 1).equals(target)) {
            count++;
        }
    }
    return count;
}

Classic: reverse a string

✏️ Your turn — reverse

Write a static method reverse(String s) that returns s backwards. Build a result String by looping from the last index down to 0, appending each character with substring(i, i+1).

Test: reverse("hello")olleh, reverse("abcdef")fedcba.

Show solution
public static String reverse(String s) {
    String result = "";
    for (int i = s.length() - 1; i >= 0; i--) {
        result += s.substring(i, i + 1);
    }
    return result;
}

Classic: contains a substring

✏️ Your turn — contains

Write a static method contains(String haystack, String needle) that returns true if needle appears anywhere in haystack. Loop i from 0 to haystack.length() - needle.length() inclusive, and at each position check haystack.substring(i, i + needle.length()).equals(needle).

Test: contains("hello world", "world") → true, contains("hello world", "xyz") → false.

Show solution
public static boolean contains(String haystack, String needle) {
    for (int i = 0; i <= haystack.length() - needle.length(); i++) {
        if (haystack.substring(i, i + needle.length()).equals(needle)) {
            return true;
        }
    }
    return false;
}
💡 Loop-bound trick

When looking for substrings of length k, loop i from 0 to length() - k inclusive. Past that causes IndexOutOfBounds.

2.8 Nested Iteration & Code Analysis

A loop inside a loop. The inner loop runs completely for each outer iteration.

Classic: multiplication table

✏️ Your turn — 5×5 times table

Use two nested for-loops (rows 1-5, cols 1-5) and System.out.printf("%4d", row * col) to print a 5×5 multiplication table. println() after each row.

Show solution
public class Main {
    public static void main(String[] args) {
        for (int row = 1; row <= 5; row++) {
            for (int col = 1; col <= 5; col++) {
                System.out.printf("%4d", row * col);
            }
            System.out.println();
        }
    }
}

Classic: triangle of stars

✏️ Your turn — star triangle

With int n = 5;, print a triangle so row r contains r stars separated by spaces:

*
* *
* * *
* * * *
* * * * * 

Use nested for-loops. Outer loop iterates rows, inner loop prints row stars.

Show solution
public class Main {
    public static void main(String[] args) {
        int n = 5;
        for (int row = 1; row <= n; row++) {
            for (int col = 1; col <= row; col++) {
                System.out.print("* ");
            }
            System.out.println();
        }
    }
}

Counting iterations precisely

For for (int i = a; i < b; i += step), iterations ≈ (b - a) / step.

  • for (int i = 0; i < 10; i++) → 10 iterations
  • for (int i = 0; i <= 10; i++) → 11 iterations
  • for (int i = 1; i <= 10; i += 2) → 5 iterations

Informal run-time sense

  • One loop over N items → O(N)
  • Two nested loops, both N → O(N²)
  • Halving each step (binary search) → O(log N)

Tracing nested loops by hand

✏️ Your turn — predict, then verify

Before running: by hand, count how many times total++ executes when i goes from 1 to 4 and j goes from i to 4. Write your guess down.

Then write the code below and run it to verify. (Expected: 10.)

Show solution
public class Main {
    public static void main(String[] args) {
        int total = 0;
        for (int i = 1; i <= 4; i++) {
            for (int j = i; j <= 4; j++) {
                total++;
            }
        }
        System.out.println(total);   // 4 + 3 + 2 + 1 = 10
    }
}

🎯 Unit 2 Review Quiz

1. How many times does this loop body execute?
for (int i = 3; i < 12; i += 2) { ... }
A 4
B 5
C 9
D 12
2. What is total after this code?
int total = 0;
for (int i = 1; i <= 3; i++)
  for (int j = 1; j <= i; j++)
    total += j;
A 6
B 10
C 9
D 18
3. After this code, what is x?
int x = 10;
if (x > 5) x = 20;
else if (x > 0) x = 30;
else x = 40;
A 10
B 20
C 30
D 40
4. Which is equivalent to !(x > 5) || (y == 10) when x = 3, y = 5?
A true
B false
C Compile error
D Cannot determine