if / else Statements
Basic if Statement
public class IfDemo {
public static void main(String[] args) {
int age = 20;
// Simple if
if (age >= 18) {
System.out.println("You can vote!");
}
// if-else
if (age >= 18) {
System.out.println("Adult");
} else {
System.out.println("Minor");
}
// if-else if-else
if (age < 13) {
System.out.println("Child");
} else if (age < 18) {
System.out.println("Teenager");
} else if (age < 65) {
System.out.println("Adult");
} else {
System.out.println("Senior");
}
}
}
Condition Expressions
// Boolean conditions
boolean isActive = true;
if (isActive) {
System.out.println("Active");
}
// Comparison operators
int x = 10;
if (x > 5 && x < 15) {
System.out.println("In range");
}
// Combined conditions
String role = "admin";
boolean hasAccess = true;
if (role.equals("admin") || hasAccess) {
System.out.println("Access granted");
}
// Null checks
String name = null;
if (name != null && !name.isEmpty()) {
System.out.println("Name: " + name);
}
Single-Line if
// Without braces (not recommended)
if (age >= 18) vote();
// With braces (recommended)
if (age >= 18) {
vote();
}
// Ternary as alternative
String status = (age >= 18) ? "Adult" : "Minor";
Nested if Statements
Nested Conditionals
public class NestedIf {
public static void main(String[] args) {
boolean hasTicket = true;
boolean isVIP = false;
// Nested if
if (hasTicket) {
if (isVIP) {
System.out.println("VIP entrance");
} else {
System.out.println("Regular entrance");
}
} else {
System.out.println("No entry");
}
// Flattened (often cleaner)
if (!hasTicket) {
System.out.println("No entry");
} else if (isVIP) {
System.out.println("VIP entrance");
} else {
System.out.println("Regular entrance");
}
}
}
Early Return Pattern
// Instead of deep nesting, use early return
public String processUser(User user) {
if (user == null) {
return "Invalid user";
}
if (!user.isActive()) {
return "User inactive";
}
if (user.getAge() < 18) {
return "User too young";
}
// Main logic here (not nested)
return "Processing: " + user.getName();
}
Guard Clauses
// Guard clauses reduce nesting
public double calculateDiscount(double price, String coupon) {
// Guard clauses
if (price <= 0) return 0;
if (coupon == null) return 0;
if (coupon.isEmpty()) return 0;
// Main logic
if (coupon.equals("SAVE10")) {
return price * 0.10;
} else if (coupon.equals("SAVE20")) {
return price * 0.20;
}
return 0;
}
switch Statement
Basic switch Statement
public class SwitchDemo {
public static void main(String[] args) {
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;
case 4:
System.out.println("Thursday");
break;
case 5:
System.out.println("Friday");
break;
case 6:
System.out.println("Saturday");
break;
case 7:
System.out.println("Sunday");
break;
default:
System.out.println("Invalid day");
break;
}
}
}
Fall-Through
// Intentional fall-through for multiple cases
public class FallThrough {
public static void main(String[] args) {
int month = 2;
String season;
switch (month) {
case 3: case 4: case 5:
season = "Spring";
break;
case 6: case 7: case 8:
season = "Summer";
break;
case 9: case 10: case 11:
season = "Fall";
break;
case 12: case 1: case 2:
season = "Winter";
break;
default:
season = "Unknown";
break;
}
System.out.println(season); // Winter
}
}
switch on Strings
// switch works with strings (Java 7+)
public class StringSwitch {
public static void main(String[] args) {
String command = "START";
switch (command) {
case "START":
System.out.println("Starting...");
break;
case "STOP":
System.out.println("Stopping...");
break;
case "PAUSE":
System.out.println("Pausing...");
break;
default:
System.out.println("Unknown command");
}
}
}
switch on Enums
public enum Direction {
NORTH, SOUTH, EAST, WEST
}
public class EnumSwitch {
public static void main(String[] args) {
Direction dir = Direction.NORTH;
switch (dir) {
case NORTH:
System.out.println("Going up");
break;
case SOUTH:
System.out.println("Going down");
break;
case EAST:
System.out.println("Going right");
break;
case WEST:
System.out.println("Going left");
break;
}
}
}
Switch Expression (Java 14+)
Modern Switch Expression
public class SwitchExpression {
public static void main(String[] args) {
int day = 3;
// Switch expression (Java 14+)
String dayName = switch (day) {
case 1 -> "Monday";
case 2 -> "Tuesday";
case 3 -> "Wednesday";
case 4 -> "Thursday";
case 5 -> "Friday";
case 6 -> "Saturday";
case 7 -> "Sunday";
default -> "Invalid";
};
System.out.println(dayName); // Wednesday
}
}
Multi-line Switch Expression
public class MultiLineSwitch {
public static void main(String[] args) {
int score = 85;
// Multi-line with braces
String grade = switch (score / 10) {
case 10, 9 -> {
System.out.println("Excellent!");
yield "A";
}
case 8 -> {
System.out.println("Good job!");
yield "B";
}
case 7 -> "C";
case 6 -> "D";
default -> "F";
};
System.out.println(grade); // B
}
}
Pattern Matching (Java 21+)
// Pattern matching in switch (preview)
public class PatternSwitch {
static String format(Object obj) {
return switch (obj) {
case Integer i -> "Integer: " + i;
case String s -> "String: " + s;
case int[] arr -> "Array of size: " + arr.length;
case null -> "Null";
default -> "Unknown: " + obj.getClass();
};
}
public static void main(String[] args) {
System.out.println(format(42)); // Integer: 42
System.out.println(format("Hello")); // String: Hello
System.out.println(format(null)); // Null
}
}
Switch vs if-else
// Use switch when:
// - Comparing single variable to constants
// - Many cases for same variable
// - Clean fall-through needed
// Use if-else when:
// - Complex conditions
// - Range comparisons
// - Different variables
Common Mistakes
Mistake 1: Missing break
// WRONG: missing break causes fall-through
switch (day) {
case 1:
System.out.println("Monday");
// fall-through!
case 2:
System.out.println("Tuesday");
// fall-through!
default:
System.out.println("Other");
}
// If day=1, prints: Monday, Tuesday, Other
// RIGHT: always include break
switch (day) {
case 1:
System.out.println("Monday");
break;
case 2:
System.out.println("Tuesday");
break;
default:
System.out.println("Other");
break;
}
Mistake 2: Using mutable objects in switch
// WRONG: switch on mutable String
String status = "active";
switch (status) {
case "active":
System.out.println("Active");
break;
}
// OK, but status could be changed elsewhere
// BETTER: use constants or enums
final String STATUS = "active";
switch (STATUS) { ... }
Mistake 3: Deeply nested if
// WRONG: deep nesting
if (condition1) {
if (condition2) {
if (condition3) {
if (condition4) {
// deep logic
}
}
}
}
// RIGHT: guard clauses
if (!condition1) return;
if (!condition2) return;
if (!condition3) return;
if (!condition4) return;
// main logic
Mistake 4: Null switch
// WRONG: switch on null
String s = null;
// switch (s) { ... } // NullPointerException!
// RIGHT: check first
if (s != null) {
switch (s) { ... }
}
Best Practices
- Always include break in switch (unless intentional fall-through)
- Use switch expressions for cleaner code (Java 14+)
- Use guard clauses to reduce nesting
- Prefer enums over magic strings/numbers
- Use pattern matching for type checks (Java 21+)
Practice Problems
What is the output of this code?
Example:
Input: public class Test { public static void main(String[] args) { int x = 1; switch (x) { case 1: System.out.print("One "); case 2: System.out.print("Two "); case 3: System.out.print("Three "); } } }
Output: One Two Three
No break statements, so execution falls through all cases.
Optimal Solution — O(1) time, O(1) space
Understand switch fall-through behavior
public class Test {
public static void main(String[] args) {
int x = 1;
switch (x) {
case 1:
System.out.print("One ");
// no break - falls through
case 2:
System.out.print("Two ");
// no break - falls through
case 3:
System.out.print("Three ");
}
}
}Edge Cases:
- Intentional fall-through
- Multiple cases
What is the output of this code?
Example:
Input: public class Test { public static void main(String[] args) { int a = 5, b = 10, c = 15; if (a > b) { if (b > c) { System.out.println("A"); } else { System.out.println("B"); } } else { System.out.println("C"); } } }
Output: C
a (5) is not > b (10), so the else branch executes.
Optimal Solution — O(1) time, O(1) space
Trace through nested conditions
public class Test {
public static void main(String[] args) {
int a = 5, b = 10, c = 15;
if (a > b) { // 5 > 10 is false
if (b > c) {
System.out.println("A");
} else {
System.out.println("B");
}
} else {
System.out.println("C"); // executes
}
}
}Edge Cases:
- Equal values
- All conditions false
Find and fix the bug in this code.
Example:
Input: public class Bug { public static void main(String[] args) { String fruit = "apple"; String color; switch (fruit) { case "apple": color = "red"; case "banana": color = "yellow"; default: color = "unknown"; } System.out.println(color); } }
Output: unknown
Missing break causes fall-through. Even though fruit is 'apple', color gets overwritten to 'unknown'.
Optimal Solution — O(1) time, O(1) space
Add break statements
public class Bug {
public static void main(String[] args) {
String fruit = "apple";
String color;
switch (fruit) {
case "apple":
color = "red";
break; // add break!
case "banana":
color = "yellow";
break; // add break!
default:
color = "unknown";
break;
}
System.out.println(color); // red
}
}Edge Cases:
- Intentional fall-through
- Null cases
Quiz
1. What happens when a switch case is missing a break?
2. What is the benefit of switch expressions (Java 14+)?
3. When should you use if-else instead of switch?
4. What is the output of this code? int x=2; switch(x){ case 1: System.out.print("A"); case 2: System.out.print("B"); case 3: System.out.print("C"); }
Flashcards
Question
What is fall-through in switch statements?
Click to reveal answer
Answer
When a case is missing break, execution continues to the next case. This can be intentional or a bug.
Question
What is the difference between if-else and switch?
Click to reveal answer
Answer
if-else handles complex conditions and ranges. switch is cleaner for comparing a single variable to constants.
Question
What is a guard clause?
Click to reveal answer
Answer
An early return or exit that reduces nested if statements. Makes code flatter and more readable.
Question
What does yield do in switch expressions?
Click to reveal answer
Answer
yield returns a value from a switch expression block (multi-line case). Used in Java 14+ switch expressions.
Question
What is if / else / switch?
Click to reveal answer
Answer
if / else / switch is a key concept in Java programming.
Revision Notes
Key Takeaways
- 1.Missing break in switch causes fall-through
- 2.Switch expressions (Java 14+) are cleaner and safer
- 3.Use guard clauses to reduce nested if statements
- 4.Prefer switch for comparing single variable to constants
- 5.Use if-else for complex conditions and ranges
Interview Tips
- •Know switch fall-through behavior
- •Explain when to use switch vs if-else
- •Use guard clauses for cleaner code
- •Practice pattern matching in switch (Java 21+)
Cheat Sheet
Control Flow Cheat Sheet
if-else:
if (condition) { ... }
else if (condition) { ... }
else { ... }
switch:
switch (value) {
case 1: ...; break;
case 2: ...; break;
default: ...; break;
}
switch expression (Java 14+):
String s = switch (x) {
case 1 -> "one";
case 2 -> "two";
default -> "other";
};
Best Practices:
- Always use break in switch
- Use guard clauses to reduce nesting
- Prefer enums over magic strings