Loops: Repeating Code

Duration: 45 min

Loops: Repeating Code

Duration: 45 min

Introduction

Loops are the foundation of efficient programming. Instead of writing the same code multiple times, you write it once and tell Java to repeat it. Loops are everywhere: processing each item in a collection, retrying a network request, reading lines from a file, or animating frames in a game. Mastering loops is essential to writing clean, maintainable code.

This module covers all major loop types in Java: for loops, while loops, do-while loops, and enhanced for loops. You'll learn when to use each, how to control loop execution with break and continue, and patterns for nested loops and common tasks.

For Loops

The traditional for loop is ideal when you know exactly how many times to repeat. It has three parts: initialization, condition, and update.

public class ForLoopDemo {
    public static void main(String[] args) {
        // Basic for loop: print numbers 1 to 5
        for (int i = 1; i <= 5; i++) {
            System.out.println("Number: " + i);
        }

// Counting down for (int countdown = 3; countdown >= 1; countdown--) { System.out.println(countdown); } System.out.println("Blastoff!");

// Skip by 2 for (int i = 0; i <= 10; i += 2) { System.out.print(i + " "); // 0 2 4 6 8 10 }

// Multiplication table System.out.println("\n5x Table:"); for (int i = 1; i <= 10; i++) { System.out.println("5 × " + i + " = " + (5 * i)); } } }

The for loop declaration for (int i = 1; i <= 5; i++) means: start with i at 1, repeat as long as i is 5 or less, and increment i by 1 after each iteration. The variable i is scoped to the loop—it only exists inside those curly braces.

While Loops

While loops repeat as long as a condition is true. Use them when you don't know in advance how many iterations you need.

public class WhileLoopDemo {
    public static void main(String[] args) {
        // Input validation: keep asking until valid
        int userAge = 0;
        while (userAge < 1 || userAge > 150) {
            // Simulate user input
            userAge = 42;  // Replace with Scanner in real code
            if (userAge < 1 || userAge > 150) {
                System.out.println("Invalid age. Try again.");
                break;  // Exit for demo purposes
            }
        }

// Doubling until threshold int value = 1; while (value < 1000) { System.out.print(value + " "); value *= 2; } System.out.println(); // 1 2 4 8 16 32 64 128 256 512

// Simulating API retries int attempts = 0; int maxAttempts = 3; while (attempts < maxAttempts) { System.out.println("Attempt " + (attempts + 1)); attempts++; // In real code: if (successfulConnection()) break; } } }

While loops are perfect for tasks where the iteration count depends on external factors: reading user input until validation passes, retrying operations with backoff, processing data until a sentinel value appears.

Do-While Loops

A do-while loop guarantees at least one execution, even if the condition is initially false. It's useful for menu systems and validated input.

public class DoWhileDemo {
    public static void main(String[] args) {
        // Menu system
        String choice;
        do {
            System.out.println("\n=== Menu ===");
            System.out.println("1. Play");
            System.out.println("2. Settings");
            System.out.println("3. Exit");
            choice = "3";  // Simulate user input
            
            switch (choice) {
                case "1" -> System.out.println("Starting game...");
                case "2" -> System.out.println("Adjusting settings...");
                case "3" -> System.out.println("Goodbye!");
                default -> System.out.println("Invalid choice");
            }
        } while (!choice.equals("3"));

// Input validation - guaranteed to ask at least once int score; do { score = 85; // Simulate user input if (score < 0 || score > 100) { System.out.println("Score must be 0-100"); } } while (score < 0 || score > 100); System.out.println("Score accepted: " + score); } }

The do-while loop always executes its body at least once, then checks the condition. This is different from while, which checks before executing.

Enhanced For Loop

The enhanced for loop (also called foreach) iterates over arrays and collections without managing index variables.

public class EnhancedForDemo {
    public static void main(String[] args) {
        String[] fruits = {"Apple", "Banana", "Cherry", "Date"};
        
        // Enhanced for: clean and simple
        for (String fruit : fruits) {
            System.out.println("Fruit: " + fruit);
        }

// Processing numbers int[] scores = {85, 90, 78, 95, 88}; int total = 0; for (int score : scores) { total += score; } System.out.println("Average: " + (total / scores.length));

// Works with any collection java.util.List colors = java.util.Arrays.asList("Red", "Green", "Blue"); for (String color : colors) { System.out.println("Color: " + color); }

// 2D array iteration int[][] matrix = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; for (int[] row : matrix) { for (int value : row) { System.out.print(value + " "); } } } }

Enhanced for loops are simpler and less error-prone than traditional for loops when you don't need the index. However, if you need the index or need to modify while iterating, use a traditional for loop instead.

Break and Continue

Break exits a loop immediately. Continue skips the rest of the current iteration and moves to the next one.

public class BreakContinueDemo {
    public static void main(String[] args) {
        // Break: find first even number greater than 50
        System.out.println("First even > 50:");
        for (int i = 51; i <= 100; i++) {
            if (i % 2 == 0) {
                System.out.println(i);
                break;  // Exit loop
            }
        }

// Continue: print odd numbers only System.out.println("Odd numbers 1-10:"); for (int i = 1; i <= 10; i++) { if (i % 2 == 0) { continue; // Skip this iteration } System.out.print(i + " "); }

// Break in nested loop (breaks inner loop only) System.out.println("\n\nSearching for target (15):"); int[][] data = { {1, 2, 3}, {4, 5, 6}, {10, 15, 20} }; boolean found = false; for (int i = 0; i < data.length && !found; i++) { for (int j = 0; j < data[i].length; j++) { if (data[i][j] == 15) { System.out.println("Found 15 at [" + i + "][" + j + "]"); found = true; break; // Breaks inner loop only } } } } }

Break and continue are powerful for flow control, but overuse makes code hard to follow. Sometimes refactoring into a method is clearer than complicated break logic.

Nested Loops

Nested loops repeat loops within loops. They're essential for processing multi-dimensional arrays, generating combinations, and algorithms like sorting.

public class NestedLoopsDemo {
    public static void main(String[] args) {
        // Multiplication table
        System.out.println("Multiplication Table (1-5):");
        for (int i = 1; i <= 5; i++) {
            for (int j = 1; j <= 5; j++) {
                System.out.printf("%2d ", i * j);
            }
            System.out.println();
        }

// Generate all pairs System.out.println("\nAll pairs from [1,2,3] and [A,B]:"); int[] numbers = {1, 2, 3}; char[] letters = {'A', 'B'}; for (int num : numbers) { for (char letter : letters) { System.out.print("(" + num + "," + letter + ") "); } }

// Find duplicates in array System.out.println("\n\nFinding duplicates:"); int[] values = {1, 2, 3, 2, 4, 3, 5}; for (int i = 0; i < values.length; i++) { for (int j = i + 1; j < values.length; j++) { if (values[i] == values[j]) { System.out.println("Duplicate: " + values[i]); } } } } }

Nested loops have O(n²) time complexity—be careful with large datasets. Three nested loops become O(n³) and quickly become slow.

Common Loop Patterns

Pattern 1: Summing and Counting

int[] numbers = {10, 20, 30, 40};
int sum = 0;
for (int num : numbers) {
    sum += num;
}
System.out.println("Sum: " + sum);  // 100

Pattern 2: Finding Maximum/Minimum

int[] temps = {72, 85, 68, 91, 78};
int max = temps[0];
for (int temp : temps) {
    if (temp > max) {
        max = temp;
    }
}
System.out.println("Highest: " + max);  // 91

Pattern 3: Transforming Values

int[] prices = {10, 20, 30};
for (int i = 0; i < prices.length; i++) {
    prices[i] = prices[i] * 2;  // Double each price
}

Pattern 4: Filtering

int[] scores = {45, 72, 55, 88, 90};
System.out.print("Passing scores: ");
for (int score : scores) {
    if (score >= 70) {
        System.out.print(score + " ");
    }
}

Loop Efficiency Tips

1. Avoid expensive operations in loop conditions 2. Cache collection sizes outside the loop 3. Use break/continue to skip unnecessary iterations 4. Prefer enhanced for when you don't need indices 5. Be careful with nested loops on large datasets

Loop Optimization and Best Practices

Avoiding Infinite Loops

public class LoopSafety {
    // INFINITE - watch out!
    // while (true) { }
    
    // Use counters with limits
    int maxRetries = 5;
    int retries = 0;
    while (retries < maxRetries) {
        // Try operation
        retries++;
    }
    
    // For loops inherently have bounds
    for (int i = 0; i < 100; i++) {
        // Safe - will execute exactly 100 times
    }
}

Early Termination Strategies

public class EarlyTermination {
    public static int findTarget(int[] array, int target) {
        // Returns immediately when found
        for (int i = 0; i < array.length; i++) {
            if (array[i] == target) {
                return i;  // Early return
            }
        }
        return -1;  // Not found
    }
    
    public static boolean contains(int[] array, int value) {
        // Uses break to exit loop
        boolean found = false;
        for (int num : array) {
            if (num == value) {
                found = true;
                break;
            }
        }
        return found;
    }
}

Advanced Loop Patterns

Processing Results in Windows

public class SlidingWindow {
    public static void processConsecutive(int[] nums, int windowSize) {
        for (int i = 0; i <= nums.length - windowSize; i++) {
            int sum = 0;
            for (int j = i; j < i + windowSize; j++) {
                sum += nums[j];
            }
            System.out.println("Window sum: " + sum);
        }
    }
}

Parallel Processing with Nested Loops

public class Matrix {
    public static int[][] transpose(int[][] matrix) {
        int rows = matrix.length;
        int cols = matrix[0].length;
        int[][] result = new int[cols][rows];
        
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                result[j][i] = matrix[i][j];
            }
        }
        return result;
    }
}

Common Loop Errors and Solutions

Error 1: Off-by-One Errors

// WRONG - prints 0-9, missing 10
for (int i = 0; i < 10; i++) {
    System.out.println(i);
}

// CORRECT - prints 0-10 inclusive for (int i = 0; i <= 10; i++) { System.out.println(i); }

Error 2: Modifying Collection While Iterating

// WRONG - throws ConcurrentModificationException
ArrayList list = new ArrayList<>();
list.add("a");
list.add("b");
for (String item : list) {
    if (item.equals("a")) {
        list.remove(item);  // Don't do this!
    }
}

// CORRECT - use iterator java.util.Iterator iter = list.iterator(); while (iter.hasNext()) { if (iter.next().equals("a")) { iter.remove(); } }

Error 3: Variable Scope in Nested Loops

// WRONG - j doesn't exist after outer loop
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        // j only exists here
    }
    // System.out.println(j);  // ERROR
}

Testing and Debugging Loops

public class LoopTesting {
    public static void debugLoop() {
        for (int i = 0; i < 5; i++) {
            System.out.println("Iteration " + i);  // Debug output
            if (i == 2) {
                System.out.println("  -> Skipping");
                continue;
            }
            System.out.println("  -> Processing");
        }
    }
}

Key Takeaways

1. For loops when you know the iteration count in advance 2. While loops when the count depends on external conditions 3. Do-while loops when you need at least one execution 4. Enhanced for loops for iterating collections without managing indices 5. Break exits the entire loop; continue skips to next iteration 6. Nested loops process multi-dimensional data but watch for O(n²) complexity 7. Common patterns: summing, finding max/min, filtering, transforming 8. Guard against infinite loops with proper termination conditions 9. Use early returns or break statements to exit loops immediately 10. Be careful with off-by-one errors when setting loop bounds

Quiz

Question 1: How many times does this loop execute?

for (int i = 1; i <= 5; i++) {
    System.out.println(i);
}
  • A) 4 times
  • B) 5 times ✓
  • C) 6 times
  • D) Infinite times

Question 2: What's the output?

for (int i = 5; i > 0; i--) {
    if (i == 3) continue;
    System.out.print(i + " ");
}
  • A) 5 4 3 2 1
  • B) 5 4 2 1 ✓
  • C) 5 4 2 1 0
  • D) Compilation error

Question 3: Which loop is best for reading user input until validation passes?

  • A) for loop
  • B) while loop ✓
  • C) do-while loop ✓
  • D) enhanced for loop

Question 4: What does this code print?

for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 2; j++) {
        if (j == 1) break;
        System.out.print("X");
    }
}
  • A) XX
  • B) XXX ✓
  • C) XXXXXX
  • D) X

Question 5: When would you use an enhanced for loop?

  • A) When you need the index value
  • B) When iterating over all elements of a collection without modification ✓
  • C) When you need to modify elements
  • D) When iterating backwards

Question 6: What's the time complexity of a nested loop with two levels?

  • A) O(n)
  • B) O(log n)
  • C) O(n²) ✓
  • D) O(1)