Control Structures
If-else, switch expressions, for, while, do-while loops, break, continue and labeled break
Control Structures
Control structures govern the execution flow of a program. Without them, every program would be a single sequential list of instructions.
1. Definition
What? Control structures are language constructs that determine the order in which statements are executed â conditionally, repeatedly, or by skipping certain blocks entirely.
Why? Every real-world program requires decisions and repetition. if, switch, for, while, and their companions are the building blocks of business logic, validation, data processing, and dynamic behavior.
Where?
- Business rule evaluation (
if/else,switch) - Collection and array traversal (
for,for-each,while) - Input validation (
do-while) - State machines and routing (
switch expression) - Complex iteration control (
break,continue, labeled break)
2. Core Concepts
2.1 Conditional Branching
| Structure | Description | When to Use |
|---|---|---|
if / else |
Basic conditional branch | 1â3 branches, boolean condition |
if / else if / else |
Multi-way conditional | Multiple mutually exclusive conditions |
switch (classic) |
Value-based branching | One variable, several concrete values |
switch expression (Java 14+) |
Value-returning switch | Assigning to a variable, cleaner syntax |
Ternary ? : |
Inline conditional | Simple value assignment |
2.2 Loops
| Structure | Description | Typical Use |
|---|---|---|
for |
Counter-based loop | Known iteration count, index needed |
for-each (for(T x : coll)) |
Iterator-based loop | Full traversal of collection/array |
while |
Pre-test loop | Condition-dependent repetition |
do-while |
Post-test loop | At least one execution required |
2.3 Control Transfer Statements
| Keyword | Effect |
|---|---|
break |
Exits the current loop or switch |
continue |
Skips the remainder of the current iteration |
return |
Exits the method (optionally returning a value) |
yield (Java 14+) |
Returns a value from a switch expression block |
labeled break |
Exits a labeled outer loop |
labeled continue |
Jumps to the next iteration of a labeled outer loop |
2.4 Evolution of `switch`
Java 1.0 â classic switch (int, char)
Java 5 â enum support
Java 7 â String support
Java 14 â switch expression (preview â standard)
Java 17 â pattern matching in switch (preview)
Java 21 â pattern matching in switch (finalized)
3. Practical Application
Which Loop Should You Choose?
| Situation | Recommended Structure |
|---|---|
| Full array/list traversal, no index needed | for-each |
| Index needed or step â +1 | for |
| Condition-dependent repetition, may run 0 times | while |
| Must execute at least once (e.g., menu prompt) | do-while |
| Infinite service loop | while(true) + break |
When `switch` vs `if-else`?
switch: single variable with multiple concrete values, enum routing, state machinesif-else: boolean expressions, range checks (x > 10), combining multiple variablesswitchexpression (Java 14+): when the branch produces a value- Pattern matching switch (Java 21+): type checking + casting in one construct
4. Code Examples
4.1 Classic Switch â â Fall-through Bug
// â BAD â missing break causes fall-through
switch (day) {
case MONDAY:
System.out.println("Monday");
// missing break!
case TUESDAY:
System.out.println("Tuesday"); // also prints for MONDAY!
break;
default:
System.out.println("Other day");
}
// â
GOOD â explicit break in every branch
switch (day) {
case MONDAY:
System.out.println("Monday");
break;
case TUESDAY:
System.out.println("Tuesday");
break;
default:
System.out.println("Other day");
}
4.2 Switch Expression (Java 14+)
// â
Modern switch expression â no fall-through, returns a value
String type = switch (statusCode) {
case 200, 201 -> "Success";
case 301, 302 -> "Redirect";
case 404 -> "Not Found";
case 500 -> "Server Error";
default -> "Unknown";
};
4.3 Switch Expression with `yield`
int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
default -> {
String s = day.toString();
int result = s.length();
yield result; // yield returns the block's value
}
};
4.4 Pattern Matching in Switch (Java 21+)
// â
Type checking + casting combined in switch
static String format(Object obj) {
return switch (obj) {
case Integer i -> String.format("int: %d", i);
case Long l -> String.format("long: %d", l);
case String s -> String.format("String: %s", s);
case null -> "null";
default -> obj.toString();
};
}
4.5 Guarded Pattern (Java 21+)
static String classify(Shape shape) {
return switch (shape) {
case Circle c when c.radius() > 100 -> "large circle";
case Circle c -> "small circle";
case Rectangle r when r.area() > 1000 -> "large rectangle";
case Rectangle r -> "small rectangle";
default -> "unknown";
};
}
4.6 Labeled Break â Exiting Nested Loops
// â
Labeled break to exit the outer loop
outer:
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] == target) {
System.out.println("Found at [" + i + "][" + j + "]");
break outer; // exits the OUTER loop
}
}
}
4.7 Off-by-One Error
// â BAD â ArrayIndexOutOfBoundsException
for (int i = 0; i <= arr.length; i++) { // should be < not <=
System.out.println(arr[i]);
}
// â
GOOD
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
4.8 Input Validation with `do-while`
// â
At least one execution guaranteed
int value;
do {
System.out.print("Enter a positive number: ");
value = scanner.nextInt();
} while (value <= 0);
4.9 `break` vs `continue`
// break â exits the loop entirely
for (int i = 0; i < 10; i++) {
if (i == 5) break; // loop ends, i = 5
System.out.println(i); // prints 0, 1, 2, 3, 4
}
// continue â skips to next iteration
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) continue; // skip even numbers
System.out.println(i); // prints 1, 3, 5, 7, 9
}
5. Trade-offs
| Aspect | Details |
|---|---|
| Readability | for-each > for > while for collection traversal. switch expression > if-else chain when 4+ branches. |
| Performance | The JIT compiler optimizes most loops to equivalent native code. for-each on an array compiles to the same bytecode as an indexed for. |
switch vs if-else |
switch on integers and Strings generates tableswitch/lookupswitch bytecode â faster than an if-else chain for many branches. |
| Fall-through | Classic switch fall-through can be useful for intentional grouping, but is error-prone. Switch expressions eliminate fall-through entirely. |
| Labeled break | Powerful for nested loops, but overuse hurts readability â consider refactoring into a method instead. |
6. Common Mistakes
| Mistake | Description | Prevention |
| ---------------------------- | ----------------------------------------------------- | ------------------------------------------- | ------------------------------------------------- | ---------------------------------------------- |
| Missing break | Fall-through in classic switch | Use switch expressions (Java 14+) |
| Off-by-one | <= instead of < (or vice versa) in array indexing | Use for-each when index is not needed |
| Infinite loop | Loop condition never becomes false | Always verify the loop variable is modified |
| Boolean short-circuit | && and | | are short-circuit â side effects may be skipped | Avoid side-effecting expressions in conditions |
| Unmodified loop variable | Forgetting to increment in while | Prefer for when a counter is needed |
| Null in switch | NullPointerException before Java 21 | Use case null -> in Java 21+ |
7. Senior-Level Knowledge
7.1 Switch Expressions are Exhaustive
Since Java 14, switch expressions must be exhaustive â every possible value must be covered, or the code won't compile. For enums, this means handling all constants or providing a default branch.
7.2 Sealed Classes + Switch (Java 17/21)
sealed interface Shape permits Circle, Rectangle, Triangle {}
record Circle(double r) implements Shape {}
record Rectangle(double w, double h) implements Shape {}
record Triangle(double a, double b, double c) implements Shape {}
// Exhaustive â no default needed when all permitted classes are covered
double area(Shape shape) {
return switch (shape) {
case Circle c -> Math.PI * c.r() * c.r();
case Rectangle r -> r.w() * r.h();
case Triangle t -> {
double s = (t.a() + t.b() + t.c()) / 2;
yield Math.sqrt(s * (s - t.a()) * (s - t.b()) * (s - t.c()));
}
};
}
7.3 JIT Optimizations on Loops
- Loop unrolling: the JIT unrolls small fixed-size loops
- Loop vectorization: uses SIMD instructions where possible
- Bounds check elimination: if the JIT can prove the index is always valid, it removes array bounds checks
- Loop inversion: transforms
whileintodo-whilefor better branch prediction
7.4 At the Bytecode Level
tableswitch: for contiguous value ranges (O(1) lookup)lookupswitch: for sparse values (O(log n) binary search)- String switch:
hashCode()-basedlookupswitch+equals()verification
8. Glossary
| Term | Definition |
|---|---|
| Control structure | A construct that directs the order of statement execution |
| Conditional branch | if/else, ternary â choosing paths based on conditions |
| Loop | Repeated execution of a block |
| Pre-test loop | while â condition checked before each iteration |
| Post-test loop | do-while â condition checked after each iteration |
| Labeled break | Exiting an outer loop by label |
| Fall-through | Execution falling into the next case in classic switch |
| Switch expression | A value-returning switch (Java 14+) |
| Pattern matching | Type-checking + destructuring in one step |
| Exhaustive | Complete coverage â every case is handled |
| Guarded pattern | A pattern with a when condition |
| Yield | Keyword that returns a value from a switch expression block |
9. Quick Reference
if/elseâ boolean conditions, 1â3 branchesswitch(classic) â one variable's concrete values, watch out forbreakswitchexpression (Java 14+) â->syntax, no fall-through, returns a value- Pattern matching switch (Java 21+) â type checks,
whenguards,case null forâ known iteration count, index neededfor-eachâ collection/array traversal, no indexwhileâ 0 or more repetitions, condition firstdo-whileâ at least 1 execution, condition lastbreakâ exit loop/switchcontinueâ skip to next iterationreturnâ exit methodyieldâ return a value from a switch expression block- Labeled
break/continueâ multi-level loop control - Sealed classes + switch â exhaustive pattern matching, no
defaultneeded - JIT:
tableswitch= O(1),lookupswitch= O(log n)
đź Games
8 questions