MindIQ Academy

03 - Decision Making and Loops

A complete beginner-to-advanced guide to Java control flow, aligned with the Oracle Certified Professional: Java SE 21 Developer (1Z0-830) exam objectives.


Table of Contents

  1. What Is Control Flow?
  2. The if / else Statement
  3. The Ternary Operator
  4. The switch Statement
  5. switch Expressions (Java 14+)
  6. Pattern Matching for switch (Java 21)
  7. Loops Overview
  8. The for Loop
  9. The Enhanced for Loop
  10. The while Loop
  11. The do-while Loop
  12. break and continue
  13. Labels
  14. Certification Traps
  15. Common Mistakes
  16. Interview Questions
  17. Quick Revision Notes
  18. One-Page Cheat Sheet

1. What Is Control Flow?

Control flow is the order in which statements are executed. By default, code runs top to bottom — but decision-making and loops let you change that path.

+------------------+        +------------------+        +------------------+
|   DECISIONS      |        |     LOOPS        |        |     JUMPS        |
|  if / else       |        |  for             |        |  break           |
|  switch          |        |  while           |        |  continue        |
|  ternary ?:      |        |  do-while        |        |  return          |
+------------------+        +------------------+        +------------------+

2. The if / else Statement

The if statement runs a block only when a boolean condition is true.

Syntax Forms

// 1. simple if
if (age >= 18) {
    System.out.println("Adult");
}

// 2. if-else
if (age >= 18) {
    System.out.println("Adult");
} else {
    System.out.println("Minor");
}

// 3. if-else-if ladder
if (score >= 90) {
    grade = 'A';
} else if (score >= 80) {
    grade = 'B';
} else {
    grade = 'F';
}

Rules & Traps

RuleDetail
Condition must be booleanif (1) is a compile error (unlike C/C++).
= vs ==if (x = true) works only for booleans; if (x = 5) fails for ints.
Braces optional for one statementBut omitting them is a common bug source.
Dangling elseBinds to the nearest unmatched if.
int x = 5;
// if (x = 10) { }     // ERROR: int is not boolean
if (x == 10) { }       // OK

boolean flag = false;
if (flag = true) {      // legal but a BUG: assigns, doesn't compare
    System.out.println("runs"); // this prints!
}

The Missing-Braces Trap

if (true)
    System.out.println("A");
    System.out.println("B");   // NOT part of the if! Always runs.

Both lines look indented, but only the first belongs to the if. "B" always prints.


3. The Ternary Operator

A compact if-else that produces a value.

String result = (age >= 18) ? "Adult" : "Minor";

// nested (use sparingly)
char grade = (score >= 90) ? 'A' : (score >= 80) ? 'B' : 'C';

Type Trap

Both branches must produce compatible types:

Object o = true ? "text" : 42;   // OK: common type Object
// int x = true ? 1 : "two";     // ERROR: incompatible types

4. The switch Statement

switch selects one of many code blocks based on a value. Use it instead of long if-else-if ladders.

Classic (Colon) Syntax

int day = 3;
switch (day) {
    case 1:
        System.out.println("Monday");
        break;
    case 2:
        System.out.println("Tuesday");
        break;
    case 3:
        System.out.println("Wednesday");
        break;
    default:
        System.out.println("Other");
}

Allowed switch Types

AllowedNot Allowed
byte, short, char, intlong
String (Java 7+)float, double
enumboolean
Wrapper: Byte,Short,Character,Integerobjects (classic switch)

Fall-Through (Critical Trap)

Without break, execution falls through to the next case:

int x = 1;
switch (x) {
    case 1:
        System.out.println("One");   // prints
    case 2:
        System.out.println("Two");   // ALSO prints (no break above)
        break;
    case 3:
        System.out.println("Three");
}
// Output:
// One
// Two

Intentional Fall-Through (Grouping)

switch (day) {
    case 6:
    case 7:
        System.out.println("Weekend");
        break;
    default:
        System.out.println("Weekday");
}

Rules & Traps

RuleDetail
case labels must be compile-time constantsNo variables. final constants OK.
No duplicate case valuesCompile error.
default is optionalCan be placed anywhere (runs if no case matches).
case value must fit the switch typecase 300: for a byte switch = compile error.
String switchUses .equals()/hashCode(); null selector → NPE.

5. switch Expressions (Java 14+)

A switch expression returns a value and uses arrow (->) syntax — no fall-through, no break needed.

int day = 3;
String name = switch (day) {
    case 1 -> "Monday";
    case 2 -> "Tuesday";
    case 3 -> "Wednesday";
    default -> "Other";
};
System.out.println(name);   // Wednesday

Arrow vs Colon

FeatureColon (:)Arrow (->)
Fall-throughYes (needs break)No (each case isolated)
Returns a valueOnly via yield/assignment per caseDirectly
Multiple labelsStacked case 6: case 7:case 6, 7 ->

Multiple Labels & Blocks with yield

int day = 6;
String type = switch (day) {
    case 1, 2, 3, 4, 5 -> "Weekday";
    case 6, 7 -> "Weekend";
    default -> {
        // block body must use 'yield' to return a value
        String msg = "Invalid";
        yield msg;
    }
};

Exhaustiveness (Key Rule)

A switch expression must be exhaustive — cover every possible value, or include a default.

enum Color { RED, GREEN, BLUE }

Color c = Color.RED;
// No default needed IF all enum constants are covered:
String hex = switch (c) {
    case RED   -> "#FF0000";
    case GREEN -> "#00FF00";
    case BLUE  -> "#0000FF";
};   // exhaustive: compiles without default

If you omit a constant and have no default, it won't compile.


6. Pattern Matching for switch (Java 21)

Java 21 makes switch work on types and patterns, not just constants. This is a flagship exam topic.

Type Patterns

static String describe(Object obj) {
    return switch (obj) {
        case Integer i -> "int: " + i;
        case String s  -> "string of length " + s.length();
        case Double d  -> "double: " + d;
        case null      -> "null value";
        default        -> "unknown";
    };
}

case null is now allowed directly. Without it, a null selector throws NullPointerException.

Guarded Patterns (when)

A when clause adds a boolean condition to a pattern:

static String classify(Object obj) {
    return switch (obj) {
        case Integer i when i > 100 -> "big int";
        case Integer i              -> "small int";
        case String s when s.isBlank() -> "blank string";
        case String s               -> "string: " + s;
        default                      -> "other";
    };
}

Record Patterns (Deconstruction)

record Point(int x, int y) {}

static String locate(Object obj) {
    return switch (obj) {
        case Point(int x, int y) when x == 0 && y == 0 -> "origin";
        case Point(int x, int y) -> "point at " + x + "," + y;
        default -> "not a point";
    };
}

Pattern Matching Rules

RuleDetail
Order mattersMore specific / guarded cases must come before general ones.
Dominance checkA subtype/guard case after a broader case = compile error (unreachable).
null handlingUse case null; can combine case null, default ->.
ExhaustivenessRequired; usually needs a default (or covers a sealed hierarchy).
Type coverageWith sealed types, the compiler can verify exhaustiveness without default.
// Dominance error example:
switch (obj) {
    case Object o -> "any";     // too broad, first
    // case String s -> "str";  // ERROR: unreachable (Object already matched)
}

7. Loops Overview

LoopBest ForChecks Condition
forKnown number of iterationsBefore each iteration
Enhanced forIterating arrays/collectionsInternally
whileUnknown count, may run 0 timesBefore each iteration
do-whileRuns at least onceAfter each iteration
   for / while / for-each              do-while
   +----------------+                +----------------+
   | check first    |                | run body       |
   | run body       |                | check after    |
   | (0+ times)     |                | (1+ times)     |
   +----------------+                +----------------+

8. The for Loop

for (int i = 0; i < 5; i++) {
    System.out.println(i);   // 0 1 2 3 4
}

Anatomy

for ( init ; condition ; update ) { body }
       |         |          |
   runs once  checked    runs after
   at start   each pass  each pass

Variations

// multiple variables
for (int i = 0, j = 10; i < j; i++, j--) { }

// infinite loop (all parts optional)
for (;;) { break; }

// with var
for (var i = 0; i < 3; i++) { }

Scope Trap

for (int i = 0; i < 3; i++) { }
// System.out.println(i);   // ERROR: i is out of scope here

9. The Enhanced for Loop

The for-each loop iterates over arrays and Iterable collections cleanly.

int[] nums = {10, 20, 30};
for (int n : nums) {
    System.out.println(n);
}

List<String> names = List.of("Ann", "Bob");
for (String name : names) {
    System.out.println(name);
}

Limitations (Traps)

LimitationDetail
No index accessYou don't get the position; use a classic for if you need it.
Read-only of the variableReassigning the loop variable doesn't change the array/collection.
Cannot modify collection structureRemoving during for-each → ConcurrentModificationException.
Cannot iterate backwardsOnly forward traversal.
int[] arr = {1, 2, 3};
for (int x : arr) {
    x = x * 2;          // does NOT change arr — x is a copy
}
System.out.println(arr[0]);  // 1 (unchanged)

10. The while Loop

Runs while a condition is true; may run zero times.

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

Trap: Condition Must Be boolean

// while (1) { }     // ERROR: int is not boolean
while (true) { break; }   // OK: infinite loop with explicit exit

Trap: Unreachable Code

while (false) {
    System.out.println("x");   // COMPILE ERROR: unreachable statement
}

while (false) is a compile error (unreachable body), but if (false) is not — the compiler treats them differently.


11. The do-while Loop

Runs the body first, then checks the condition — so it always runs at least once.

int i = 10;
do {
    System.out.println(i);   // prints 10 once
    i++;
} while (i < 5);             // false, but body already ran

Note the semicolon after while (...) — required in do-while, forbidden after a normal while header.

Featurewhiledo-while
Condition checkBefore bodyAfter body
Minimum runs01
Trailing ;NoYes (required)

12. break and continue

KeywordEffect
breakExits the entire loop (or switch).
continueSkips to the next iteration.
// break
for (int i = 0; i < 10; i++) {
    if (i == 5) break;       // stops at 5
    System.out.print(i);     // 01234
}

// continue
for (int i = 0; i < 5; i++) {
    if (i % 2 == 0) continue; // skip even numbers
    System.out.print(i);      // 13
}

break in Nested Loops

A plain break only exits the innermost loop:

for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        if (j == 1) break;    // breaks inner loop only
        System.out.println(i + "," + j);
    }
}
// prints 0,0  1,0  2,0

13. Labels

A label names a loop so break/continue can target an outer loop directly.

outer:
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        if (i + j == 2) {
            break outer;       // exits BOTH loops
        }
        System.out.println(i + "," + j);
    }
}
// prints 0,0  0,1  1,0

continue with a Label

outer:
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        if (j == 1) continue outer;   // jump to next i
        System.out.println(i + "," + j);
    }
}
// prints 0,0  1,0  2,0

Label Rules

RuleDetail
SyntaxlabelName: immediately before a loop (or block).
break label;Exits the labeled loop entirely.
continue label;Continues the labeled loop's next iteration.
continue targetThe label must be on a loop (not an arbitrary block).
break targetCan be on any labeled block.

14. Certification Traps

#Trap
1if (x = 5) fails for ints; only booleans allow assignment in a condition.
2Missing braces: only the next single statement belongs to the if.
3Classic switch falls through without break.
4switch does not accept long, float, double, or boolean.
5case labels must be compile-time constants; no duplicates allowed.
6String/wrapper switch with a null selector → NullPointerException.
7switch expression must be exhaustive (cover all values or default).
8Arrow switch has no fall-through; colon switch does.
9A switch block returning a value needs yield (arrow blocks / colon style).
10Java 21 pattern switch: case dominance/order errors are compile-time.
11Pattern switch needs case null or it throws NPE on null.
12while (false) {} = unreachable-code compile error; if (false) {} is fine.
13for-each variable is a copy — modifying it doesn't change the source.
14Loop variable in for (int i...) is out of scope after the loop.
15do-while requires a trailing semicolon; plain while header does not.
16continue label; must target a loop, not a plain block.

15. Common Mistakes

MistakeFix
Forgetting break in classic switchAdd break or use arrow switch.
Using = instead of == in conditionsUse == for comparison.
Off-by-one in loop bounds (<= vs <)Double-check boundaries.
Infinite loop (forgetting to update counter)Ensure the condition can become false.
Modifying a collection during for-eachUse an Iterator or removeIf.
Expecting do-while to skip when false initiallyIt always runs once.
Using broad pattern case before specific onePut specific/guarded cases first.
Trying switch on a doubleUse if-else for floating-point.

16. Interview Questions

Q1. What types can a classic switch work on? byte, short, char, int, their wrappers, String, and enum. Not long, float, double, or boolean.

Q2. What is fall-through in a switch? When a case has no break, execution continues into the next case(s) until a break or the end.

Q3. How do switch expressions differ from switch statements? Expressions return a value, use -> (no fall-through), require exhaustiveness, and use yield for block bodies.

Q4. What is exhaustiveness in a switch expression? Every possible input value must be handled — via covering all cases (e.g., all enum constants / sealed subtypes) or a default.

Q5. What is pattern matching for switch (Java 21)? It lets case labels match types and deconstruct records, with optional when guards, instead of only matching constants.

Q6. Why is case null important in pattern switch? Without it, a null selector throws NullPointerException; case null handles null safely.

Q7. Difference between break and continue? break exits the loop entirely; continue skips to the next iteration.

Q8. What are labeled loops used for? To break/continue an outer loop from within nested loops.

Q9. Difference between while and do-while? while checks the condition first (0+ runs); do-while runs the body first (1+ runs).

Q10. Why does while(false){} not compile but if(false){} does? The compiler flags the while body as unreachable code; if(false) is allowed (used historically for conditional compilation).

Q11. Can you modify an array element using a for-each loop? You can change object state, but reassigning the loop variable doesn't change the array — the variable is a copy of each element.

Q12. What is case dominance in pattern switch? A broader/earlier case that makes a later, more specific case unreachable — a compile-time error.


17. Quick Revision Notes

  • if conditions must be boolean; = only works for booleans.
  • Single statement (no braces) — only that one line belongs to the if.
  • Classic switch: falls through without break; allows int/char/String/enum, not long/float/double/boolean.
  • case labels = compile-time constants, no duplicates.
  • switch expression: ->, no fall-through, must be exhaustive, yield for blocks.
  • Java 21 pattern switch: type patterns, when guards, record deconstruction, case null; order/dominance matters.
  • Sealed types let the compiler verify exhaustiveness without default.
  • for, while, for-each: check condition first (0+ runs); do-while: runs at least once + needs trailing ;.
  • while(false){} = compile error; if(false){} is fine.
  • for-each variable is a copy; can't get index or remove during iteration.
  • break/continue affect the innermost loop unless you use a label.
  • Loop variable scope ends with the loop.

18. One-Page Cheat Sheet

======================= DECISION MAKING & LOOPS CHEAT SHEET =======================

IF / ELSE
  if (cond) {...} else if (cond) {...} else {...}
  cond MUST be boolean ; if (x=5) -> ERROR (ints) ; missing braces = 1 stmt only
  ternary: type r = cond ? a : b ;  (a,b must be compatible types)

CLASSIC SWITCH (colon)
  switch(x){ case 1: ...; break; default: ...; }
  FALLS THROUGH without break
  allowed: byte short char int + wrappers, String, enum
  NOT allowed: long float double boolean
  case = compile-time constant, no duplicates ; null String selector -> NPE

SWITCH EXPRESSION (arrow, Java 14+)
  String s = switch(x){
     case 1,2,3 -> "low";
     case 4 -> { yield "four"; }   // block needs yield
     default -> "other";
  };
  NO fall-through ; MUST be exhaustive (all cases or default)

PATTERN MATCHING SWITCH (Java 21)
  switch(obj){
     case Integer i when i>100 -> "big";
     case Integer i -> "int";
     case String s -> s;
     case Point(int x,int y) -> x+","+y;   // record deconstruction
     case null -> "null";
     default -> "other";
  }
  specific/guarded cases FIRST ; dominance error = won't compile
  no case null + null selector -> NPE

LOOPS
  for(init;cond;update){...}           // 0+ runs, check first
  for(T x : iterable){...}             // for-each; x is a COPY; no index
  while(cond){...}                     // 0+ runs ; while(false){} = unreachable ERROR
  do{...}while(cond);                  // 1+ runs ; TRAILING ; required

JUMPS
  break;          // exit innermost loop / switch
  continue;       // next iteration of innermost loop
  break label;    // exit labeled (outer) loop
  continue label; // next iteration of labeled loop (must be a loop)

  outer:
  for(...) for(...) { break outer; }   // exits both
==================================================================================

End of 03 - Decision Making and Loops.