Java Control Flow: if/else, switch, loops, break and continue
Control flow statements determine the order in which instructions execute. Java provides conditionals (if/else, switch), loops (for, while, do-while, for-each), and jump statements (break, continue, return). Understanding when and how to use each, including labeled breaks for nested loops, is foundational to writing clear, correct Java code.
Contents
if / else if / else
The iftrueelse ifelsecondition ? valueIfTrue : valueIfFalseif
int score = 75;
// Simple if/else
if (score >= 90) {
System.out.println("A");
} else if (score >= 80) {
System.out.println("B");
} else if (score >= 70) {
System.out.println("C");
} else {
System.out.println("F");
}
// Ternary operator — compact single-expression conditional
String result = score >= 70 ? "Pass" : "Fail";
// Conditional with &&, ||, ! operators
boolean isAdult = true;
boolean hasTicket = false;
if (isAdult && hasTicket) {
System.out.println("Admitted");
} else if (!isAdult) {
System.out.println("Under age");
} else {
System.out.println("No ticket");
}
// Nested if — keep nesting shallow for readability
// Prefer early return (guard clause) over deeply nested if
String classify(int n) {
if (n < 0) return "negative";
if (n == 0) return "zero";
if (n % 2 == 0) return "positive even";
return "positive odd";
}
switch statement and switch expression
The traditional switchcasebreakswitch->yieldintString
// Traditional switch statement (fall-through unless break is used)
String day = "MONDAY";
switch (day) {
case "MONDAY":
case "TUESDAY":
case "WEDNESDAY":
case "THURSDAY":
case "FRIDAY":
System.out.println("Weekday");
break;
case "SATURDAY":
case "SUNDAY":
System.out.println("Weekend");
break;
default:
System.out.println("Unknown");
}
// Switch expression (Java 14+) — arrow syntax, no fall-through, yields a value
String type = switch (day) {
case "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY" -> "Weekday";
case "SATURDAY", "SUNDAY" -> "Weekend";
default -> "Unknown";
};
// Switch expression with blocks and yield
int numLetters = switch (day) {
case "MONDAY", "FRIDAY", "SUNDAY" -> 6;
case "TUESDAY" -> 7;
case "THURSDAY", "SATURDAY" -> 8;
default -> {
System.out.println("Unexpected: " + day);
yield day.length(); // yield returns the value from a block
}
};
// Switch on integers and strings — both supported
int code = 2;
String label = switch (code) {
case 1 -> "ONE";
case 2 -> "TWO";
case 3 -> "THREE";
default -> "OTHER";
};
for, while, and do-while
Java has three general-purpose loops. The classic forwhiledo-whilebreak
// Classic for loop — index-based
for (int i = 0; i < 5; i++) {
System.out.print(i + " "); // 0 1 2 3 4
}
// Multiple variables in for loop
for (int i = 0, j = 10; i < j; i++, j--) {
System.out.println("i=" + i + " j=" + j);
}
// while loop — condition checked before body
int n = 10;
int sum = 0;
while (n > 0) {
sum += n;
n--;
}
System.out.println(sum); // 55
// do-while — body executes at least once
int input;
do {
input = readInput(); // hypothetical input method
} while (input < 0);
// Infinite loop with break
while (true) {
String line = readLine();
if (line == null || line.isEmpty()) break;
process(line);
}
// Iterating backwards
for (int i = list.size() - 1; i >= 0; i--) {
System.out.println(list.get(i));
}
Enhanced for-each loop
The enhanced forIterable<T>removeIfIterator
// for-each over an array
int[] numbers = {1, 2, 3, 4, 5};
for (int n : numbers) {
System.out.print(n + " ");
}
// for-each over a List
List<String> names = List.of("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println(name);
}
// for-each over a Map's entrySet
Map<String, Integer> scores = Map.of("Alice", 90, "Bob", 85);
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
System.out.println(entry.getKey() + " → " + entry.getValue());
}
// for-each works with any Iterable
Iterable<Path> paths = FileSystems.getDefault().getRootDirectories();
for (Path p : paths) {
System.out.println(p);
}
// Cannot modify collection during for-each (use iterator or removeIf instead)
// WRONG — throws ConcurrentModificationException:
// for (String s : names) { if (s.startsWith("A")) names.remove(s); }
// CORRECT:
names = new ArrayList<>(names);
names.removeIf(s -> s.startsWith("A")); // safe
Iterable<T>for(int i=0...)break, continue, and labeled jumps
breakswitchcontinuebreak outercontinue outerreturn
// break — exits the innermost enclosing loop or switch
for (int i = 0; i < 10; i++) {
if (i == 5) break;
System.out.print(i + " "); // 0 1 2 3 4
}
// continue — skips the rest of the current iteration
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) continue; // skip even numbers
System.out.print(i + " "); // 1 3 5 7 9
}
// Labeled break — exits a specific outer loop by label
outer:
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 5; col++) {
if (row == 2 && col == 3) {
System.out.println("Found at [" + row + "][" + col + "]");
break outer; // exits both loops
}
}
}
// Labeled continue — skip to next iteration of an outer loop
outer:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (j == 1) continue outer; // skip rest of inner, advance outer
System.out.println("i=" + i + " j=" + j);
}
}
// Prints: i=0 j=0, i=1 j=0, i=2 j=0
// Prefer extracting nested loops into a method with early return
// over labeled break/continue — cleaner code
boolean containsPair(int[][] matrix, int target) {
for (int[] row : matrix)
for (int val : row)
if (val == target) return true; // early return instead of labeled break
return false;
}
breakcontinuereturn