Control Statements, Boolean Logic, and Loops in Java

Fundamentals of Program Control Flow

  • Sequential Execution Baseline: Standard computer programs execute sequentially from top to bottom, beginning at line 11 and proceeding sequentially to the final statement.

  • Control Statements: Mechanisms that alter the sequential flow of program execution through a method fall into two distinct structural categories:

    • Conditionals (Selection Statements): Enable decision-making by selecting alternative execution paths based on evaluated conditions.

    • Loops (Repetition Statements): Enable repetitive execution of code blocks based on evaluated conditions.

  • Boolean Foundation: Both conditional statements and loops rely entirely on boolean expressions that evaluate strictly to either true or false.

Selection Statements: If, Else, and Multi-Branch Logic

  • Conditional Statement Definition: A selection statement permits a program to determine which action or block of statements to execute next at runtime.

  • Java Selection Statements:

    • In Java (specifically on the AP Computer Science A Examination), selection is implemented using if and if-else statements.

    • switch statements exist within Java syntax but are explicitly excluded from the AP Computer Science A syllabus.

  • The Basic if Statement:

    • Evaluates a boolean expression. If the condition evaluates to true, the subsequent statement or enclosed block executes; if false, execution bypasses the body entirely.


Java Scanner input and basic if conditional statement
  • Implementation example: java import java.util.Scanner; class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.in); System.out.print("What is your grade on the test? "); int grade = scan.nextInt(); if (grade >= 80) System.out.println("Good job"); } }     

  • The Two-Way if-else Statement:

    • Directs program flow between two mutually exclusive alternatives. When the boolean expression is true, the if block executes; when false, the else block executes.


If-else statement branching example
  • Implementation example: java if (grade >= 80) System.out.println("Good job"); else System.out.println("Someone's in trouble!!");     

  • Nested if Statements vs. Chained else if Ladders:

    • Deep nesting places subsequent conditional branches inside nested else blocks, which quickly degrades code readability with multiple indentation levels and braces.


Deeply nested if-else statements for grade evaluation
  • Chaining using else if creates a flat, sequential decision ladder that evaluates each condition in order until a true condition is met, bypassing all remaining branches.


Chained else-if conditional statements
  • Chained grading scale implementation: java if (grade == 100) System.out.println("You were perfect!! A+"); else if (grade >= 90) System.out.println("You got an A!"); else if (grade >= 80) System.out.println("You got a B."); else if (grade >= 70) System.out.println("You got a C."); else if (grade >= 60) System.out.println("You got a D...you might want a tutor"); else System.out.println("You failed...please get tutoring");     

  • Conditional Flow Tracing and Dangling Else Resolution:

    • In Java, an else clause binds to the closest preceding unmatched if within the same block scope.

    • Tracing problem: java int a = /* unknown value */; int b = /* unknown value */; if (a > 0) if (b < 0) System.out.print("A"); else if (a > 5) System.out.print("B"); else System.out.print("C"); else System.out.print("D"); &nbsp;&nbsp;&nbsp;&nbsp;

    • Execution paths to reach each output:

    • Path to "A": Requires a>0a > 0 and b<0b < 0.

    • Path to "B": Requires a>0a > 0, b≥0b \ge 0, and a>5a > 5.

    • Path to "C": Requires a>0a > 0, b≥0b \ge 0, and a≤5a \le 5 (that is, 0<a≤50 < a \le 5 with b≥0b \ge 0).

    • Path to "D": Requires a≤0a \le 0 (bypassing the outer if entirely, regardless of bb).

  • Minimum Value Determination Task:

    • Algorithm requirement: Accept three integers from user input via a Scanner instance, evaluate their relative values using selection statements, and output the minimum integer.

Relational and Equality Operators

  • Operator Inventory:

    • == : Equal to

    • != : Not equal to

    • < : Less than

    • <= : Less than or equal to

    • > : Greater than

    • >= : Greater than or equal to

  • Strict Primitive Usage Rule:

    • Relational operators (<, <=, >, >=) and equality operators (==, !=) are strictly intended for primitive data types (int, double, boolean, char).

    • Applying == or != to object reference variables compares memory references (memory addresses) rather than the underlying contents of the objects.

Logical Operators and Boolean Algebra

  • Java Logical Operators:

    • ! (Logical NOT): Unary operator that negates the boolean value. If a is true, !a is false; if a is false, !a is true.

    • && (Logical AND): Binary operator that yields true if and only if both left and right operands evaluate to true. Yields false otherwise.

    • || (Logical OR): Binary operator that yields true if either the left operand, right operand, or both operands evaluate to true. Yields false only when both operands evaluate to false.

  • Evaluating Compound Boolean Expressions:


Evaluation of two integer inputs with logical AND and OR operators
  • Code snippet: java import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.in); System.out.print("Type two integers: "); int num1 = scan.nextInt(); int num2 = scan.nextInt(); if (num1 > 5 && num2 < 8) System.out.println("AAA"); else if (num1 > 5 || num2 < 8) System.out.println("BBB"); else System.out.println("CCC"); } } &nbsp;&nbsp;&nbsp;&nbsp;

  • Input conditions and output mappings:

    • "AAA" Output: Both conditions must hold: num1>5num1 > 5 and num2<8num2 < 8 (e.g., num1=6num1 = 6, num2=7num2 = 7).

    • "BBB" Output: The first condition fails, but at least one sub-condition holds: ¬(num1>5∧num2<8)∧(num1>5∨num2<8)\neg(num1 > 5 \land num2 < 8) \land (num1 > 5 \lor num2 < 8) (e.g., num1=6num1 = 6, num2=10num2 = 10 or num1=2num1 = 2, num2=7num2 = 7).

    • "CCC" Output: Neither condition holds: num1≤5num1 \le 5 and num2≥8num2 \ge 8 (e.g., num1=4num1 = 4, num2=9num2 = 9).

  • Short-Circuit Evaluation:

    • Java optimizes compound boolean expressions by evaluating operands strictly from left to right, terminating evaluation the instant the result is guaranteed:

    • In a && b, if a is false, the entire expression must evaluate to false; operand b is never evaluated.

    • In c || d, if c is true, the entire expression must evaluate to true; operand d is never evaluated.

    • Practical Utility (Guard Expressions): Prevents fatal runtime errors such as division by zero or null reference exceptions: java if (count != 0 && sum / count > 90) System.out.println("Great job, an A average!"); &nbsp;&nbsp;&nbsp;&nbsp;

    • If count=0count = 0, the expression count != 0 evaluates to false. Short-circuiting guarantees sum / count > 90 is bypassed, preventing an ArithmeticException (/ by zero).

  • De Morgan's Laws:

    • Logical equivalences governing the distribution of negation across conjunctions and disjunctions:

    • ¬(A∧B)≡¬A∨¬B\neg(A \land B) \equiv \neg A \lor \neg B (in Java: !(A && B) is equivalent to !A || !B)

  • ¬(A∨B)≡¬A∧¬B\neg(A \lor B) \equiv \neg A \land \neg B (in Java: !(A || B) is equivalent to !A && !B)

  • Negating relational operators:

    • !(a >= b) simplifies to a < b

    • !(a < b) simplifies to a >= b

    • !(a == b) simplifies to a != b

Analytical Boolean Problems and Proofs

  • Problem 1 (Contradiction Analysis):

    • Expression: (x && y) && !(x || y)

    • Analytical simplification:

    • By De Morgan's Law: !(x || y) is equivalent to !x && !y.

    • The expression becomes (x && y) && (!x && !y).

    • Rearranging terms yields (x && !x) && (y && !y).

    • Because x && !x evaluates to false under all circumstances, the overall expression evaluates to false always.

    • Truth table verification:

xx

yy

x && y

x || y

!(x || y)

(x && y) && !(x || y)

true

true

true

true

false

false

true

false

false

true

false

false

false

true

false

true

false

false

false

false

false

false

true

false

  • Problem 2 (Relational Precedence and Arithmetic):

    • Expression: (3 + 4 == 5) != (3 + 4 >= 5)

    • Step-by-step reduction:

    1. Evaluate arithmetic operations: 3+4=73 + 4 = 7.

    2. Evaluate left relational expression: 7 == 5 evaluates to false.

    3. Evaluate right relational expression: 7 >= 5 evaluates to true.

    4. Evaluate boolean inequality: false != true evaluates to true.

  • Problem 3 (Conjunctive Absorption with Negated Disjunction):

    • Expression: a && !(b || a)

    • Step-by-step reduction:

    1. Apply De Morgan's Law: !(b || a) simplifies to !b && !a.

    2. Substitute back: a && !b && !a.

    3. Commute operands: (a && !a) && !b.

    4. Because a && !a evaluates unconditionally to false, the entire expression is always false.

  • Problem 4 (Tautology / Law of Excluded Middle):

    • Expression: (x && y) || !(x && y)

    • Analytical structure:

    • Let P=(x∧y)P = (x \land y).

    • The expression conforms to the fundamental tautology P∨¬PP \lor \neg P.

    • Any boolean expression ORed with its exact negation evaluates to always true.

  • Problem 5 (Three-Variable De Morgan Application):

    • Target expression: !x || !y || z

    • Analytical reduction:

    • Group first two disjuncts: (!x || !y) || z.

    • By De Morgan's Law, !x || !y is logically equivalent to !(x && y).

    • Recombining gives !(x && y) || z.

  • Problem 6 (Negating Compound Relational Logic):

    • Target expression: !((a >= b) && !(c < d))

    • Analytical reduction:

    • Apply De Morgan's Law across outer negation: !(a >= b) || !(!(c < d)).

    • Invert !(a >= b) into a < b.

    • Eliminate double negation !(!(c < d)) into c < d.

    • Final equivalent expression: (a < b) || (c < d).

String and Object Comparison

  • Object Reference Equality vs. Content Equality:

    • The equality operator == checks whether two reference variables point to the exact same memory address on the heap.

    • The .equals() method inspects the state/content of the objects to determine lexical equivalence.

    • Relational comparison operators (<, <=, >, >=) cannot be applied to String objects or any non-primitive objects in Java; attempting to do so generates a compiler error.

  • The .compareTo() Method Mechanics:

    • Syntax: string1.compareTo(string2)

    • Lexicographical comparison based on underlying Unicode/ASCII numerical values:

    • Returns a negative integer if string1 precedes string2 alphabetically.

    • Returns 00 if string1 is identical in content to string2.

    • Returns a positive integer if string1 follows string2 alphabetically.

    • ASCII Precedence Detail: Uppercase letters ('A' through 'Z', ASCII values 6565 through 9090) precede lowercase letters ('a' through 'z', ASCII values 9797 through 122122). Thus, uppercase characters are numerically "less than" lowercase characters.

  • Reference Trace of String Comparisons:

    • Variable declarations: java String word1 = "ants"; String word2 = "bears"; String word3 = "cats"; String word4 = "ants"; String word5 = "Tigers"; String word6 = new String("ants"); &nbsp;&nbsp;&nbsp;&nbsp;

    • Evaluation outcomes:

    • word1.equals(word4) : true (contents match: "ants" vs "ants")

    • word1 == word4 : true (string literal pooling maps both references to the identical interned memory address)

    • word1.compareTo(word2) : negative # ('a' precedes 'b')

    • word2.compareTo(word3) : negative # ('b' precedes 'c')

    • word3.compareTo(word4) : positive # ('c' follows 'a')

    • word4.compareTo(word5) : positive # (lowercase 'a' has ASCII 9797, uppercase 'T' has ASCII 8484; 97>8497 > 84)

    • word1.equals(word6) : true (both store identical character sequences "ants")

    • word1 == word6 : false (word6 was created using new, allocating a distinct object on the heap with a distinct address)

  • String Method Applications in Conditionals:


Comparison of String equals method versus indexOf method
  • input.toLowerCase().equals("yes"): Tests for exact whole-word match, normalizing case.

  • input.indexOf("yes") != -1: Tests whether the substring "yes" appears anywhere within the input string.

  • Independent if statements vs if-else: When two standalone if statements are used sequentially, both code blocks can execute if both conditions evaluate to true.

    • Alphabetical Word Ordering Implementation:


Using compareTo method to sort words alphabetically
  • Code snippet: java System.out.print("Type in two words: "); String w1 = scan.next(); String w2 = scan.next(); if (w1.compareTo(w2) < 0) System.out.println(w1 + " comes before " + w2); else if (w1.compareTo(w2) > 0) System.out.println(w1 + " comes after " + w2); else System.out.println("You typed the same word twice!!"); &nbsp;&nbsp;&nbsp;&nbsp;

Compound Assignment and Increment/Decrement Operators

  • Operator Behavior and Expanded Equivalents:

    • = : Assignment (x = y assigns the value of y into x).

    • ++ : Increment (x++ adds 11 to x; equivalent to x = x + 1).

    • -- : Decrement (x-- subtracts 11 from x; equivalent to x = x - 1).

    • += : Addition then assignment (x += y is equivalent to x = x + y).

    • += (String context) : String concatenation then assignment (x += y appends string y to string x).

    • -= : Subtraction then assignment (x -= y is equivalent to x = x - y).

    • *= : Multiplication then assignment (x *= y is equivalent to x = x * y).

    • /= : Division then assignment (x /= y is equivalent to x = x / y).

    • %= : Remainder/Modulus then assignment (x %= y is equivalent to x = x % y).

Repetition Statements: While Loops

  • While Loop Structure:

    • Evaluates a boolean condition prior to each iteration.

    • The loop body continues executing repeatedly until the tested condition evaluates to false.

    • If the condition is false upon initial check, the loop body executes zero times.

  • Infinite Loops:

    • Occur when the tested condition never transitions to false.


Infinite while loop caused by missing loop update
  • Cause: In the code above, int i = 0; while (i <= 1000) System.out.println(i);, the loop control variable i is never incremented, creating an infinite loop that repeatedly outputs 00.

    • Sentinel-Controlled Loops:

  • Continue iterating until a specific value (the sentinel value) is supplied by user input or an external source.


Sentinel-controlled while loop awaiting user input
  • Example: java import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.in); String input = ""; while (input.equals("STOP") == false) { System.out.print("Do you want to play a game? "); input = scan.nextLine(); } System.out.println("Fine! You don't have to yell!!"); } } &nbsp;&nbsp;&nbsp;&nbsp;

  • Integer Digit Reversal Algorithm:


Reversing integer digits using modulo and integer division
  • Algorithmic mechanics:

    • Extract the lowest-order digit via modulo 1010: num % 10.

    • Shift existing reversed digits left by one base-1010 power: temp *= 10.

    • Append the extracted digit: temp += num % 10.

    • Truncate the lowest-order digit from the original number via integer division by 1010: num /= 10.

    • Terminate when num == 0.

  • Complete code: java public static int reverse(int num) { int temp = 0; while (num != 0) { temp *= 10; temp += num % 10; num /= 10; } return temp; } &nbsp;&nbsp;&nbsp;&nbsp;

  • String Filtering and Accumulation via While Loop:

    • Code snippet: java String text = "AP COMPUTER SCIENCE A"; String x = ""; int loc = 0; while (loc < text.length()) { if (text.substring(loc, loc + 1).compareTo("M") <= 0 && !text.substring(loc, loc + 1).equals(" ")) x += text.substring(loc, loc + 1); loc++; } System.out.println(x); &nbsp;&nbsp;&nbsp;&nbsp;

    • Trace analysis: Accumulates characters from "AP COMPUTER SCIENCE A" that are lexicographically ≤"M"\le \text{"M"} and not equal to a space character:

    • 'A' (≤M\le M) -> accumulated

    • 'P' (>M> M) -> skipped

    • ' ' (space) -> skipped

    • 'C' (≤M\le M) -> accumulated

    • 'O' (>M> M) -> skipped

    • 'M' (≤M\le M) -> accumulated

    • 'P', 'U', 'T' (>M> M) -> skipped

    • 'E' (≤M\le M) -> accumulated

    • 'R', ' ', 'S' -> skipped

    • 'C', 'I', 'E' (≤M\le M) -> accumulated

    • 'N' (>M> M) -> skipped

    • 'C', 'E' (≤M\le M) -> accumulated

    • ' ' -> skipped

    • 'A' (≤M\le M) -> accumulated

    • Final value printed: "ACMECEICEA".

  • Nested While Loops (Multiplication Table):

    • Nested repetition structures execute the entire inner loop cycle for each individual iteration of the outer loop.

    • Implementation (10×1010 \times 10 grid): java int x = 1; while (x <= 10) { int y = 1; while (y <= 10) { System.out.print(x * y + "\t"); y++; } System.out.println(); x++; } &nbsp;&nbsp;&nbsp;&nbsp;

Repetition Statements: For Loops

  • Loop Selection Criteria:

    • while loops: Preferred when the number of iterations is unknown prior to entering the loop (indefinite iteration, such as awaiting specific user input or state changes).

    • for loops: Preferred when the exact number of iterations is known or fixed in advance (definite iteration, such as counting over ranges or traversing fixed structures).

  • Header Components and Scope:


Diagram of a for loop header components
  • A standard for loop header consists of three segments separated by semicolons: for (initialization; conditional statement; increment/decrement)

    1. Initialization: Declares and assigns the loop control variable (e.g., int i = 1). Crucial scope rule: Variables declared within the for loop header exist strictly within the loop's block scope and cannot be referenced outside the loop.

    2. Conditional Statement: Evaluated before every iteration (e.g., i < 100). The body executes only if this evaluates to true.

    3. Update (Increment/Decrement): Executes immediately following each execution of the loop body (e.g., i++).

  • Table of squares example: java System.out.println("SQUARES"); for (int i = 1; i < 100; i++) System.out.println(i + "\t" + i * i); &nbsp;&nbsp;&nbsp;&nbsp;

  • Structural Equivalence between for and while Loops:

    • A definite counting loop written as a for loop: java for (int i = 0; i < 1000; i++) { System.out.println(i); } &nbsp;&nbsp;&nbsp;&nbsp;

  • The functionally equivalent while loop: java int i = 0; while (i < 1000) { System.out.println(i); i++; } &nbsp;&nbsp;&nbsp;&nbsp;

    • Note on scope difference: In the while implementation, i remains in scope after loop termination, whereas in the for implementation, i goes out of scope.

  • String Traversal using for Loops:

    • Filtering characters lexicographically (<"M"< \text{"M"}) from "HELLO WORLD": java String text = "HELLO WORLD"; for (int i = 0; i < text.length(); i++) { if (text.substring(i, i + 1).compareTo("M") < 0) System.out.println(text.substring(i, i + 1)); } &nbsp;&nbsp;&nbsp;&nbsp;

    • Execution trace on "HELLO WORLD":

    • Index 00: 'H' (<M< M) -> prints "H"

    • Index 11: 'E' (<M< M) -> prints "E"

    • Index 22: 'L' (<M< M) -> prints "L"

    • Index 33: 'L' (<M< M) -> prints "L"

    • Index 44: 'O' (>M> M) -> skipped

    • Index 55: ' ' (Space ASCII 32<7732 < 77) -> prints " "

    • Index 66: 'W' (>M> M) -> skipped

    • Index 77: 'O' (>M> M) -> skipped

    • Index 88: 'R' (>M> M) -> skipped

    • Index 99: 'L' (<M< M) -> prints "L"

    • Index 1010: 'D' (<M< M) -> prints "D"

  • Modulo and Compound Filter Tracing:

    • Code snippet: java String text = "Rusty Curry"; for (int i = 0; i < text.length(); i++) { if (text.substring(i, i + 1).equals("s") || i % 3 == 0) System.out.print(text.substring(i, i + 1)); } &nbsp;&nbsp;&nbsp;&nbsp;

  • Tracing indices of "Rusty Curry":

    • Index 00: 'R' (0%3==00 \% 3 == 0) -> prints "R"

    • Index 11: 'u' (1%3≠01 \% 3 \ne 0, not "s") -> skipped

    • Index 22: 's' (equals "s") -> prints "s"

    • Index 33: 't' (3%3==03 \% 3 == 0) -> prints "t"

    • Index 44: 'y' -> skipped

    • Index 55: ' ' -> skipped

    • Index 66: 'C' (6%3==06 \% 3 == 0) -> prints "C"

    • Index 77: 'u' -> skipped

    • Index 88: 'r' -> skipped

    • Index 99: 'r' (9%3==09 \% 3 == 0) -> prints "r"

    • Index 1010: 'y' -> skipped

    • Complete output: "RstCr".

  • Nested for Loops (Star Pattern Generation):

    • Implementation: java for (int i = 0; i < 10; i++) { for (int j = 0; j < i; j++) System.out.print("*"); System.out.println(); } &nbsp;&nbsp;&nbsp;&nbsp;

  • Behavior: Generates a triangular star display. When i=0i = 0, the inner loop executes 00 times (prints a newline). For each subsequent line from i=1i = 1 to i=9i = 9, exactly ii asterisks are printed, producing lines of lengths 00 through 99.

String Traversal Patterns and Idioms

  • Standard Forward Traversal:

    • Using a for loop: java for (int i = 0; i < text.length(); i++) { String ch = text.substring(i, i + 1); } &nbsp;&nbsp;&nbsp;&nbsp;

  • Using a while loop: java int i = 0; while (i < text.length()) { String ch = text.substring(i, i + 1); i++; } &nbsp;&nbsp;&nbsp;&nbsp;

  • Reverse Traversal:

    • To process characters from right to left, initialize at text.length() - 1 and decrement down to index 00: java for (int i = text.length() - 1; i >= 0; i--) { String ch = text.substring(i, i + 1); } &nbsp;&nbsp;&nbsp;&nbsp;

  • Pattern-Matching / Substring Elimination Traversal:

    • Loops conditioned on indexOf search for targets and iteratively modify the source string: java while (text.indexOf(something) != -1) { // code modifying text to eventually render condition false } &nbsp;&nbsp;&nbsp;&nbsp;

Algorithmic Implementations and Projects

  • Algorithm 1: Sum of Divisible Integers (sumDivisible):

    • Problem Specification: Compute the sum of all integers between start and end (inclusive) that are evenly divisible by divisor. Return −1-1 if start > end.

    • Implementation: java public static int sumDivisible(int start, int end, int divisor) { if (start > end) return -1; int sum = 0; for (int i = start; i <= end; i++) { if (i % divisor == 0) sum += i; } return sum; } &nbsp;&nbsp;&nbsp;&nbsp;

  • Algorithm 2: Counting Adjacent Double Letters (countDoubleLetters):

    • Problem Specification: Count occurrences where two identical characters appear directly adjacent in a string (e.g., "bookkeeper" returns 33 for 'oo', 'kk', and 'ee').

    • Implementation: java public static int countDoubleLetters(String str) { int count = 0; for (int i = 0; i < str.length() - 1; i++) { if (str.substring(i, i + 1).equals(str.substring(i + 1, i + 2))) count++; } return count; } &nbsp;&nbsp;&nbsp;&nbsp;

    • Boundary safety: Loop terminates at str.length() - 1 to ensure substring(i + 1, i + 2) does not throw a StringIndexOutOfBoundsException at the string's final character.

  • Game Implementation 1: Guess My Number (User Guesses):


Number guessing game class structure
  • Logic requirements:

    • Generate random integer in [1,100][1, 100] via 1 + (int)(max * Math.random()).

    • Prompt user for guesses iteratively.

    • If guess << target, print "Too Low…" (higher).

    • If guess >> target, print "Too High…" (lower).

    • Terminate loop when guess equals target, output total guess count, and print a concluding message.

    • Game Implementation 2: High Low Game Version 2.0 (Computer Guesses):


High Low Game Version 2 console session
  • Logic requirements:

    • The user holds an integer in mind within a specified range.

    • Computer maintains lower and upper bounds, generating guesses within the current interval.

    • User enters feedback: "higher" (computer adjusts lower bound), "lower" (computer adjusts upper bound), or "correct".

    • Repeat iteratively until user enters "correct", then output total guesses taken.

    • Major Project: Decision Tree Simulation Games:

  • Game variants: "Rock, Paper, Scissors", "Rock, Paper, Scissors, Lizard, Spock", and "Giants, Wizards, Elves".

  • Decision Rules for "Giants, Wizards, Elves":

    • Giants beat Elves: Giants squash Elves.

    • Elves beat Wizards: Elves outsmart Wizards and chew at their legs.

    • Wizards beat Giants: Wizards zap Giants with a magic spell.