Loops in Java — for, for-each and while compared with Python

Loops in Java work with the same logic as Python — repeat a block of code multiple times. What changes is the syntax and one new addition: the for-each loop that Java has and Python’s for already covers implicitly. If you understood loops in Python and C, Java loops will feel immediately familiar with a few small adjustments.

The for loop with index

Java’s for loop is identical to C’s — three parts separated by semicolons inside the parentheses:

# Python
for i in range(5):
    print(i)
// Java
for (int i = 0; i < 5; i++) {
    System.out.println(i);
}

The three parts:

int i = 0 — initialisation. Runs once before the loop starts.

i < 5 — condition. Checked before each iteration. Loop continues while true.

i++ — update. Runs after each iteration.

Python range() equivalents

// range(n) → 0 to n-1
for (int i = 0; i < n; i++) { }

// range(1, n+1) → 1 to n
for (int i = 1; i <= n; i++) { }

// range(0, n, 2) → step 2
for (int i = 0; i < n; i += 2) { }

// range(n, 0, -1) → countdown
for (int i = n; i > 0; i--) { }

Variable scope in the for loop

A variable declared inside the for only exists within that loop — same as C:

for (int i = 0; i < 5; i++) {
    System.out.println(i);
}
System.out.println(i);    // compile error — i doesn't exist here

If you need the variable after the loop, declare it before:

int i;
for (i = 0; i < 5; i++) { }
System.out.println("Final i: " + i);    // → 5

The for-each loop — iterating collections

Java has a dedicated loop for iterating over arrays and collections without an index counter. This is Java’s equivalent of Python’s for x in list::

# Python
grades = [7.5, 8.0, 6.5, 9.0]
for grade in grades:
    print(grade)
// Java for-each
double[] grades = {7.5, 8.0, 6.5, 9.0};
for (double grade : grades) {
    System.out.println(grade);
}

The syntax: for (type variable : array_or_collection). The : reads as “in” — “for each double grade in grades”.

When to use for-each vs for with index

// Use for-each — when you only need the value
for (double grade : grades) {
    System.out.printf("%.2f%n", grade);
}

// Use for with index — when you need the position
for (int i = 0; i < grades.length; i++) {
    System.out.printf("Grade %d: %.2f%n", i + 1, grades[i]);
}

// Use for with index — when you need to modify elements
for (int i = 0; i < grades.length; i++) {
    grades[i] = grades[i] * 1.1;    // can't do this with for-each
}

For-each cannot modify the array elements — it works on a copy of each value. To modify the array you need the index.

Arrays in Java — basics

Since for-each requires an array, here are the essentials:

// Declare and initialise
int[] numbers = {1, 2, 3, 4, 5};
double[] grades = {7.5, 8.0, 6.5};
String[] names = {"Sergio", "María", "Carlos"};

// Declare with size — elements default to 0 / false / null
int[] arr = new int[10];      // 10 integers, all 0
double[] d = new double[5];   // 5 doubles, all 0.0

// Access
System.out.println(numbers[0]);    // → 1 (0-based index)
numbers[0] = 99;                   // assign

// Length
System.out.println(numbers.length);    // → 5 (not length(), no parentheses)

length is a property (no parentheses), unlike String’s length() method (with parentheses). This inconsistency is a classic Java gotcha.

The while loop

Identical concept to Python — evaluates the condition before each iteration:

# Python
counter = 0
while counter < 5:
    print(counter)
    counter += 1
// Java
int counter = 0;
while (counter < 5) {
    System.out.println(counter);
    counter++;
}

Parentheses around the condition are mandatory. Always update the condition variable inside the loop to avoid infinite loops. If you get an infinite loop, press Ctrl + C in the terminal.

Input validation with while — a common FP2 pattern

Scanner sc = new Scanner(System.in);
int option;

do {
    System.out.println("1. Option A");
    System.out.println("2. Option B");
    System.out.println("0. Exit");
    System.out.print("Choose: ");
    option = sc.nextInt();
    if (option < 0 || option > 2) {
        System.out.println("Invalid — try again");
    }
} while (option < 0 || option > 2);

The do-while loop

do-while doesn’t exist in Python. It runs the body at least once before checking the condition — the check is at the end:

// while — may never execute
while (condition) {
    // might never run if condition starts false
}

// do-while — always executes at least once
do {
    // always runs at least once
} while (condition);    // semicolon required here

The classic use case: menus that must display at least once before the user can choose to exit:

Scanner sc = new Scanner(System.in);
String response;

do {
    System.out.println("=== MENU ===");
    System.out.println("1. Do something");
    System.out.println("0. Exit");
    System.out.print("Option: ");
    response = sc.nextLine();
    // process response
} while (!response.equals("0"));

break and continue

break exits the loop immediately. continue skips to the next iteration. Identical behaviour to Python and C:

// break — exit loop
for (int i = 0; i < 10; i++) {
    if (i == 5) break;
    System.out.print(i + " ");
}
// → 0 1 2 3 4

// continue — skip 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

break in nested loops only exits the innermost loop. To exit multiple levels use a boolean flag:

boolean found = false;
for (int i = 0; i < 10 && !found; i++) {
    for (int j = 0; j < 10 && !found; j++) {
        if (i * j == 42) {
            System.out.printf("Found: i=%d, j=%d%n", i, j);
            found = true;
        }
    }
}

Traversing a String with loops

Strings in Java are not directly iterable with for-each — you need to use charAt(index):

String text = "Hello";

// for with index — most common
for (int i = 0; i < text.length(); i++) {
    char c = text.charAt(i);
    System.out.print(c + " ");
}
// → H e l l o

// Convert to char array for for-each
for (char c : text.toCharArray()) {
    System.out.print(c + " ");
}
// → H e l l o

Nested loops — multiplication table

for (int i = 1; i <= 10; i++) {
    for (int j = 1; j <= 10; j++) {
        System.out.printf("%4d", i * j);
    }
    System.out.println();
}

For each value of i the inner loop runs completely through all values of j. Total iterations: 10 × 10 = 100. %4d pads numbers to 4 characters for alignment.

A complete program — all loop types

import java.util.Scanner;

public class LoopsDemo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        double[] grades = {7.5, 3.0, 8.5, 5.0, 9.5, 4.5, 6.0};

        // FOR WITH INDEX — with position
        System.out.println("--- All grades ---");
        for (int i = 0; i < grades.length; i++) {
            System.out.printf("  Grade %d: %.2f%n", i + 1, grades[i]);
        }

        // FOR-EACH — just the values
        double sum = 0;
        int passing = 0;
        for (double grade : grades) {
            sum += grade;
            if (grade >= 5.0) passing++;
        }
        System.out.printf("%nAverage: %.2f%n", sum / grades.length);
        System.out.printf("Passing: %d/%d%n", passing, grades.length);

        // WHILE — countdown
        System.out.println("\n--- Countdown ---");
        int count = 5;
        while (count > 0) {
            System.out.print(count + "... ");
            count--;
        }
        System.out.println("GO!");

        // DO-WHILE — menu that always shows once
        System.out.println("\n--- Stats menu ---");
        String option;
        do {
            System.out.println("A. Min grade");
            System.out.println("B. Max grade");
            System.out.println("Q. Quit");
            System.out.print("Option: ");
            option = sc.nextLine().toUpperCase();

            switch (option) {
                case "A": {
                    double min = grades[0];
                    for (double g : grades) if (g < min) min = g;
                    System.out.printf("Min: %.2f%n%n", min);
                    break;
                }
                case "B": {
                    double max = grades[0];
                    for (double g : grades) if (g > max) max = g;
                    System.out.printf("Max: %.2f%n%n", max);
                    break;
                }
                case "Q":
                    System.out.println("Goodbye!");
                    break;
                default:
                    System.out.println("Invalid option\n");
            }
        } while (!option.equals("Q"));

        sc.close();
    }
}

Visualise with Python Tutor

Select Java from the dropdown and paste in pythontutor.com:

public class LoopDemo {
    public static void main(String[] args) {
        // for with index
        int sum = 0;
        for (int i = 1; i <= 5; i++) {
            sum += i;
        }
        System.out.println("Sum 1-5: " + sum);

        // for-each
        int[] numbers = {2, 4, 6, 8, 10};
        int total = 0;
        for (int n : numbers) {
            total += n;
        }
        System.out.println("Total: " + total);

        // do-while
        int x = 1;
        do {
            System.out.print(x + " ");
            x *= 2;
        } while (x <= 16);
    }
}

Step through all three loops and compare them. In the for loop watch how i is created in the frame, incremented by i++ after each iteration, and checked against 5 at the start of each. In the for-each loop watch how Java internally uses an index to access numbers[0], numbers[1] etc. — n takes each value in turn but there’s no visible index variable. In the do-while watch how the body executes with x=1 before any condition is checked — the condition x <= 16 is only evaluated at the bottom. Try setting x = 32 initially and watch the do-while still execute once before checking 32 <= 16 and immediately stopping — that unconditional first execution is the defining characteristic of do-while.

Quick summary

// FOR WITH INDEX
for (int i = 0; i < n; i++) { }       // 0 to n-1
for (int i = 1; i <= n; i++) { }      // 1 to n
for (int i = n; i > 0; i--) { }       // countdown
for (int i = 0; i < n; i += 2) { }   // step 2

// FOR-EACH — iterate values directly
for (type variable : array) { }
// Cannot modify array elements
// Cannot access index
// Cleaner when index not needed

// ARRAYS
int[] arr = {1, 2, 3};           // initialise
int[] arr = new int[10];          // 10 zeros
arr[0]                            // access element
arr.length                        // size (no parentheses!)

// WHILE
while (condition) {
    // update condition inside
}

// DO-WHILE — always runs at least once
do {
    // body
} while (condition);    // semicolon required

// WHEN TO USE EACH
// for (index)  → need position, modifying array, known count
// for-each     → only need values, cleaner iteration
// while        → unknown iterations, condition-based
// do-while     → menus, validation (need at least one execution)

// BREAK AND CONTINUE
break;       // exit loop immediately
continue;    // skip to next iteration

// STRING TRAVERSAL
for (int i = 0; i < s.length(); i++) {
    char c = s.charAt(i);
}
for (char c : s.toCharArray()) { }    // for-each on String

// PYTHON vs JAVA
// for i in range(n):    → for (int i = 0; i < n; i++)
// for x in list:        → for (Type x : array)
// while condition:      → while (condition)
// (no do-while)         → do { } while (condition);

In the next article we cover arrays and methods in Java — the first step into real object-oriented programming.

Next step: practiceJava loops practice — text, statistics and patterns

Sigue aprendiendo

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *