Skip to main content

4.2 Loops

Loops are used to make a task repeat. They continuously execute the statements inside a block as long as the given condition is true. Java has four types of loops: for, while, do-while, and the enhanced for.

1. while Loop

The while loop is mainly used when the number of iterations is not known in advance, and the repetition is determined by a condition. It keeps executing the code in the block as long as the condition is true.

Basic Structure

// Structure: while (condition) { code to repeat }

int i = 1;
while (i <= 5) {
System.out.println("Iteration " + i);
i++; // the increment expression must be written inside the block
}
// Output: Iteration 1 ~ Iteration 5

while Loop — Condition-Based Repetition

// Count how many times a number must be divided by 2 to reach 1
int n = 64;
int count = 0;

while (n != 1) {
n /= 2;
count++;
}
System.out.println("Dividing by 2 " + count + " times gives 1."); // 6 times

Caution: Infinite Loop

If the condition is always true, the program falls into an infinite loop that never ends. Be careful not to forget the increment expression.

int i = 1;
while (i <= 5) {
System.out.println(i);
// i++; <- Forgetting this makes i always 1 -> infinite loop!
}

Intentional Infinite Loop

Infinite loops can be used intentionally. Always include an exit condition (break).

import java.util.Scanner;

public class InfiniteLoopExample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int total = 0;

while (true) { // intentional infinite loop
System.out.print("Enter a number (enter 0 to stop): ");
int num = scanner.nextInt();

if (num == 0) {
break; // exit when 0 is entered
}
total += num;
System.out.println("Running total: " + total);
}

System.out.println("Final total: " + total);
scanner.close();
}
}

2. do-while Loop

A variant of the while loop that executes the block once first, then evaluates the condition. The block runs at least once even if the condition is false from the start.

Basic Structure

// Structure: do { code to repeat } while (condition);

int i = 10;
do {
System.out.println("Executed: i = " + i); // runs once even though condition is false
i++;
} while (i < 5); // 10 < 5 is false, but the block already ran once
// Output: Executed: i = 10

do-while — Menu Selection Pattern

When showing a menu to the user, at least one display is always needed, so do-while fits naturally.

import java.util.Scanner;

public class MenuExample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int choice;

do {
System.out.println("\n===== Menu =====");
System.out.println("1. New File");
System.out.println("2. Open File");
System.out.println("3. Save");
System.out.println("0. Exit");
System.out.print("Select: ");
choice = scanner.nextInt();

switch (choice) {
case 1: System.out.println("Creating a new file."); break;
case 2: System.out.println("Opening a file."); break;
case 3: System.out.println("Saving the file."); break;
case 0: System.out.println("Exiting."); break;
default: System.out.println("Invalid selection.");
}
} while (choice != 0); // repeat until 0 is selected

scanner.close();
}
}

3. for Loop

The for loop is primarily used when the number of iterations is already known. The initialization, condition, and increment are all written on one line, making it easy to read.

Basic Structure

// Structure: for (initialization; condition; increment) { code to repeat }

for (int i = 1; i <= 5; i++) {
System.out.println("Hello Java! " + i);
}
// Output: Hello Java! 1 ~ Hello Java! 5

Variations of Initialization, Condition, and Increment

// Reverse iteration
for (int i = 10; i >= 1; i--) {
System.out.print(i + " "); // 10 9 8 7 6 5 4 3 2 1
}

// Increment by 2
for (int i = 0; i <= 20; i += 2) {
System.out.print(i + " "); // 0 2 4 6 8 10 12 14 16 18 20
}

// Multiple variables with comma
for (int i = 0, j = 10; i < j; i++, j--) {
System.out.println("i=" + i + ", j=" + j);
}

Sum from 1 to N

int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i; // accumulate i in each iteration
}
System.out.println("Sum from 1 to 100: " + sum); // 5050

Variable Scope in Loops

A variable declared in the initialization of a for loop is only valid inside the for block.

for (int i = 0; i < 3; i++) {
int temp = i * 2; // temp is created fresh each iteration
System.out.println(temp);
}
// System.out.println(i); // Compile error: i cannot be used outside the for loop
// System.out.println(temp); // Compile error: temp cannot be used outside either

4. Enhanced for Loop (for-each)

Used to read-only iterate over every element of an array or collection with very concise syntax. (Added in JDK 1.5)

Basic Usage

// Structure: for (type variable : array/collection) { code to repeat }

int[] numbers = {10, 20, 30, 40, 50};

// Regular for loop
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}

// Enhanced for loop (same result, more concise)
for (int num : numbers) {
System.out.println(num);
}

Using with Collections

import java.util.List;

List<String> fruits = List.of("Apple", "Banana", "Orange", "Grape");

for (String fruit : fruits) {
System.out.println("Fruit: " + fruit);
}
Limitations of the Enhanced for Loop

With the enhanced for loop, you cannot know the index and you cannot modify array elements. If you need the index or need to modify elements, use a regular for loop.

int[] numbers = {10, 20, 30};

// Trying to modify via enhanced for — the original array is NOT changed!
for (int num : numbers) {
num = num * 2; // num is a copy, no effect on the original
}
System.out.println(numbers[0]); // still 10

// To modify the array, use a regular for loop
for (int i = 0; i < numbers.length; i++) {
numbers[i] = numbers[i] * 2; // original can be modified
}
System.out.println(numbers[0]); // 20

5. Nested Loops

You can write a loop inside a loop. When the outer loop runs once, the inner loop runs completely.

Multiplication Table

public class MultiplicationTable {
public static void main(String[] args) {
for (int dan = 2; dan <= 9; dan++) {
System.out.println("=== Table of " + dan + " ===");
for (int i = 1; i <= 9; i++) {
System.out.printf("%d x %d = %2d%n", dan, i, dan * i);
}
}
}
}

Output (partial):

=== Table of 2 ===
2 x 1 = 2
2 x 2 = 4
...

Loop Performance Tip

// Bad: calling a method in the condition every iteration
String[] arr = {"a", "b", "c", "d", "e"};
for (int i = 0; i < arr.length; i++) { // arr.length evaluated each time
System.out.println(arr[i]);
}

// Better: store the length in a variable first
int len = arr.length;
for (int i = 0; i < len; i++) { // uses the len variable
System.out.println(arr[i]);
}
No Significant Difference in Practice

Modern JVMs optimize arr.length calls. However, for methods with computation cost such as list.size(), caching the value in a variable is a good habit.

6. Practical Example 1: Star (★) Pyramid Patterns

A classic nested-loop exercise.

public class StarPatterns {
public static void main(String[] args) {
int n = 5;

// Pattern 1: Right triangle
System.out.println("Right triangle:");
for (int i = 1; i <= n; i++) {
for (int j = 0; j < i; j++) {
System.out.print("*");
}
System.out.println();
}

// Pattern 2: Inverted triangle
System.out.println("\nInverted triangle:");
for (int i = n; i >= 1; i--) {
for (int j = 0; j < i; j++) {
System.out.print("*");
}
System.out.println();
}

// Pattern 3: Equilateral triangle (pyramid)
System.out.println("\nPyramid:");
for (int i = 1; i <= n; i++) {
// print spaces
for (int j = 0; j < n - i; j++) {
System.out.print(" ");
}
// print stars
for (int j = 0; j < 2 * i - 1; j++) {
System.out.print("*");
}
System.out.println();
}

// Pattern 4: Diamond
System.out.println("\nDiamond:");
// Top half (n rows)
for (int i = 1; i <= n; i++) {
for (int j = 0; j < n - i; j++) System.out.print(" ");
for (int j = 0; j < 2 * i - 1; j++) System.out.print("*");
System.out.println();
}
// Bottom half (n-1 rows)
for (int i = n - 1; i >= 1; i--) {
for (int j = 0; j < n - i; j++) System.out.print(" ");
for (int j = 0; j < 2 * i - 1; j++) System.out.print("*");
System.out.println();
}
}
}

Output:

Right triangle:
*
**
***
****
*****

Pyramid:
*
***
*****
*******
*********

Diamond:
*
***
*****
*******
*********
*******
*****
***
*

7. Practical Example 2: Prime Number Detection

A program that finds prime numbers using nested loops and break.

public class PrimeNumbers {
public static void main(String[] args) {
int limit = 50;
int count = 0;

System.out.println("Prime numbers up to " + limit + ":");

for (int n = 2; n <= limit; n++) {
boolean isPrime = true;

// check divisibility from 2 to n-1
for (int i = 2; i < n; i++) {
if (n % i == 0) {
isPrime = false;
break; // found a divisor, no need to check further
}
}

if (isPrime) {
System.out.print(n + " ");
count++;
}
}

System.out.println("\nTotal: " + count + " primes");
}
}

Output:

Prime numbers up to 50:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47
Total: 15 primes
Prime Number Optimization

The code above checks up to i < n, but it is enough to check up to i <= Math.sqrt(n). Every composite number has a factor at or below its square root. This optimization dramatically reduces the number of checks.

for (int i = 2; i <= Math.sqrt(n); i++) { // optimized version
if (n % i == 0) {
isPrime = false;
break;
}
}

8. Loop Selection Guide

SituationRecommended Loop
Number of iterations is knownfor
Repeat while a condition holdswhile
Guarantee at least one executiondo-while
Read-only traversal of array/collectionEnhanced for
Traversal needing the indexfor
Complex exit conditionswhile(true) + break