☕ Java
for Loop
The for loop is the most widely used iteration construct in Java. It combines initialisation, condition checking, and increment/decrement into a single compact header, making the loop's structure immediately visible. Java's for loop is a count-controlled loop — it is the natural choice whenever the number of iterations is known before the loop begins. This entry covers syntax, execution flow, nested loops, loop control statements, common patterns, and performance considerations.
Syntax and Execution Flow
The for loop header has three semicolon-separated parts enclosed in parentheses: the initialisation expression, the boolean condition, and the update expression. The initialisation runs once before the loop begins. Before each iteration — including the first — the condition is evaluated; if it is false the loop exits immediately without executing the body. After each iteration the update expression runs, then the condition is re-evaluated. This means a for loop whose condition is false from the start executes its body zero times, which is the correct and expected behaviour.
The scope of a variable declared in the initialisation section is limited to the loop header and body. Declaring the loop variable inside the header (int i = 0) rather than outside is idiomatic Java and prevents accidental reuse of the variable after the loop.
Java
// ── Anatomy of a for loop ────────────────────────────────────────────
//
// for ( initialisation ; condition ; update ) {
// body
// }
//
// Execution order:
// 1. initialisation — runs ONCE before everything
// 2. condition — evaluated BEFORE each iteration (including first)
// 3. body — runs if condition is true
// 4. update — runs AFTER each body execution
// 5. back to step 2
for (int i = 0; i < 5; i++) {
System.out.println("Iteration: " + i);
}
// Output: 0 1 2 3 4
// ── Condition false from the start — body never runs ─────────────────
for (int i = 10; i < 5; i++) {
System.out.println("This never prints");
}
// No output — condition (10 < 5) is immediately false
// ── Variable scope — i only exists inside the loop ───────────────────
for (int i = 0; i < 3; i++) {
System.out.println(i);
}
// System.out.println(i); // ← compile error — i is out of scope
// ── Multiple variables in initialisation and update ───────────────────
for (int i = 0, j = 10; i < j; i++, j--) {
System.out.println("i=" + i + " j=" + j);
}
// Output: i=0 j=10 | i=1 j=9 | i=2 j=8 | i=3 j=7 | i=4 j=6
// ── Counting down ─────────────────────────────────────────────────────
for (int i = 5; i > 0; i--) {
System.out.println("Countdown: " + i);
}
// Output: 5 4 3 2 1
// ── Step other than 1 ─────────────────────────────────────────────────
for (int i = 0; i <= 20; i += 5) {
System.out.println(i); // 0 5 10 15 20
}
// ── Infinite loop (all three parts are optional) ──────────────────────
for (;;) {
// Equivalent to while (true)
// Requires a break or return to exit
if (someCondition) break;
}Iterating Over Arrays and Lists
The indexed for loop is the right choice when you need the index value during iteration — to compare adjacent elements, to update elements in place, to iterate over two collections simultaneously, or to iterate in reverse. For read-only forward iteration over a collection, the enhanced for loop is cleaner; the indexed form is superior when the position matters.
Accessing arrays by index is a constant-time O(1) operation — the JVM computes the memory address directly from the base address and index. For ArrayList, random access is also O(1). For LinkedList, random access by index is O(n) — use an iterator or enhanced for loop instead.
Java
// ── Iterating an array by index ──────────────────────────────────────
int[] scores = {85, 92, 78, 96, 88};
int sum = 0;
for (int i = 0; i < scores.length; i++) {
sum += scores[i];
}
double average = (double) sum / scores.length;
System.out.println("Average: " + average); // 87.8
// ── Modifying array elements in place ─────────────────────────────────
// Enhanced for loop gives a COPY — cannot modify original
// Index loop modifies the array directly
for (int i = 0; i < scores.length; i++) {
scores[i] = scores[i] + 5; // add 5 bonus points
}
// ── Comparing adjacent elements ───────────────────────────────────────
int[] numbers = {3, 1, 4, 1, 5, 9, 2, 6};
for (int i = 0; i < numbers.length - 1; i++) {
if (numbers[i] > numbers[i + 1]) {
System.out.println(numbers[i] + " > " + numbers[i + 1]);
}
}
// ── Iterating a List with index ───────────────────────────────────────
List<String> names = List.of("Alice", "Bob", "Carol", "Dave");
for (int i = 0; i < names.size(); i++) {
System.out.printf("[%d] %s%n", i, names.get(i));
}
// Output: [0] Alice [1] Bob [2] Carol [3] Dave
// ── Iterating in reverse ──────────────────────────────────────────────
for (int i = names.size() - 1; i >= 0; i--) {
System.out.println(names.get(i));
}
// Output: Dave Carol Bob Alice
// ── Parallel iteration over two arrays ───────────────────────────────
String[] keys = {"name", "email", "role"};
String[] values = {"Alice", "alice@example.com", "ADMIN"};
for (int i = 0; i < keys.length; i++) {
System.out.println(keys[i] + " = " + values[i]);
}Nested for Loops
A nested for loop places one loop inside the body of another. The inner loop completes all its iterations for every single iteration of the outer loop. If the outer loop runs m times and the inner loop runs n times, the body of the inner loop executes m × n times total. This O(m×n) growth means nested loops should be used with care for large inputs.
The outer loop variable controls the row (or first dimension) and the inner loop variable controls the column (or second dimension). Each variable must have a distinct name. Deeply nested loops — three or more levels — are usually a signal that the code should be refactored into methods.
Java
// ── Multiplication table ─────────────────────────────────────────────
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
System.out.printf("%4d", i * j);
}
System.out.println();
}
// Output:
// 1 2 3 4 5
// 2 4 6 8 10
// 3 6 9 12 15
// 4 8 12 16 20
// 5 10 15 20 25
// ── 2D array processing ───────────────────────────────────────────────
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int total = 0;
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[row].length; col++) {
total += matrix[row][col];
System.out.printf("%3d", matrix[row][col]);
}
System.out.println();
}
System.out.println("Sum: " + total); // 45
// ── Star pattern — outer controls rows, inner controls columns ────────
for (int row = 1; row <= 5; row++) {
for (int star = 1; star <= row; star++) {
System.out.print("* ");
}
System.out.println();
}
// Output:
// *
// * *
// * * *
// * * * *
// * * * * *
// ── Bubble sort — classic nested loop algorithm ───────────────────────
int[] arr = {64, 34, 25, 12, 22, 11, 90};
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// Swap
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
// Output: [11, 12, 22, 25, 34, 64, 90]break, continue, and Labelled Statements
break exits the innermost enclosing loop immediately, skipping any remaining iterations. continue skips the rest of the current iteration's body and jumps to the update expression, then re-evaluates the condition. Both are useful for expressing early-exit and skip-and-continue logic cleanly.
Java supports labelled break and labelled continue for nested loops. A label is an identifier followed by a colon placed before a loop statement. labelled break exits the labelled loop entirely; labelled continue skips to the update of the labelled loop. Labels should be used sparingly — they can make control flow harder to follow — but they are the cleanest way to exit a nested loop without an extra boolean flag variable.
Java
// ── break — exit the loop immediately ───────────────────────────────
int[] numbers = {3, 7, 2, 9, 4, 6, 1};
int target = 9;
int foundAt = -1;
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == target) {
foundAt = i;
break; // stop searching once found
}
}
System.out.println("Found at index: " + foundAt); // 3
// ── continue — skip this iteration, go to next ───────────────────────
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) continue; // skip even numbers
System.out.print(i + " "); // prints: 1 3 5 7 9
}
// ── Labelled break — exit an outer loop ──────────────────────────────
// Without label: must use a boolean flag (verbose)
boolean found = false;
int foundRow = -1, foundCol = -1;
outer:
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[row].length; col++) {
if (matrix[row][col] == 5) {
foundRow = row;
foundCol = col;
break outer; // exits BOTH loops
}
}
}
System.out.println("Found at [" + foundRow + "][" + foundCol + "]");
// ── Labelled continue — skip to the next outer iteration ─────────────
outer:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (j == 1) continue outer; // skip rest of inner loop
System.out.println("i=" + i + " j=" + j);
}
}
// Output: i=0 j=0 | i=1 j=0 | i=2 j=0
// (j=1 and j=2 are never reached because continue outer
// jumps to the next outer iteration before they execute)Common Patterns and Idioms
The indexed for loop appears in many canonical algorithms and patterns. Understanding these idioms — finding min/max, accumulating a result, building a string, partitioning a range — builds the muscle memory to reach for the right tool quickly. Each pattern below represents a general template that can be adapted to the specific problem at hand.
Java
// ── Pattern 1: Accumulator ────────────────────────────────────────────
// Sum, product, count, concatenation — same structure
int[] prices = {10, 25, 8, 42, 15};
int sum = 0;
double product = 1.0;
int count = 0;
for (int i = 0; i < prices.length; i++) {
sum += prices[i];
product *= prices[i];
if (prices[i] > 15) count++;
}
// ── Pattern 2: Find min/max ───────────────────────────────────────────
int min = prices[0];
int max = prices[0];
int minIndex = 0;
int maxIndex = 0;
for (int i = 1; i < prices.length; i++) { // start at 1 — skip first
if (prices[i] < min) { min = prices[i]; minIndex = i; }
if (prices[i] > max) { max = prices[i]; maxIndex = i; }
}
System.out.println("Min: " + min + " at " + minIndex);
System.out.println("Max: " + max + " at " + maxIndex);
// ── Pattern 3: Building a result string ───────────────────────────────
String[] fruits = {"apple", "banana", "cherry"};
StringBuilder sb = new StringBuilder();
for (int i = 0; i < fruits.length; i++) {
sb.append(fruits[i]);
if (i < fruits.length - 1) sb.append(", ");
}
System.out.println(sb.toString()); // apple, banana, cherry
// ── Pattern 4: Two-pointer technique ─────────────────────────────────
// Check if a string is a palindrome
String word = "racecar";
char[] chars = word.toCharArray();
boolean isPalindrome = true;
for (int left = 0, right = chars.length - 1;
left < right;
left++, right--) {
if (chars[left] != chars[right]) {
isPalindrome = false;
break;
}
}
System.out.println(word + " is palindrome: " + isPalindrome);
// ── Pattern 5: Collect matching elements ──────────────────────────────
int[] data = {3, 8, 2, 15, 7, 22, 4, 18, 11};
List<Integer> evens = new ArrayList<>();
for (int i = 0; i < data.length; i++) {
if (data[i] % 2 == 0) {
evens.add(data[i]);
}
}
System.out.println("Even numbers: " + evens); // [8, 2, 22, 4, 18]Related Topics in Control Statements
Control Statements
Control statements determine the flow of execution in a Java program. Without them, code executes line by line from top to bottom. Control statements allow the program to make decisions, repeat actions, and jump to different parts of the code based on conditions. Java provides three categories: selection statements (if, if-else, switch), iteration statements (for, while, do-while), and jump statements (break, continue, return).
if Statement
The if statement is the most fundamental control flow construct in Java. It evaluates a boolean expression and executes a block of code only if the expression is true. If the condition is false the block is skipped entirely and execution continues with the next statement after the if block.
if-else Statement
The if-else statement extends the basic if by providing an alternative block that executes when the condition is false. It guarantees that exactly one of two blocks always executes — either the if block (condition true) or the else block (condition false). The if-else-if chain extends this to choose among more than two alternatives.
Nested if
A nested if is an if statement placed inside the body of another if or else block. Nesting allows multi-level decision making — first check a broad condition, then refine with a more specific condition inside it. While nesting is sometimes necessary, deep nesting quickly reduces readability and should be refactored using guard clauses, logical operators, or extracted methods.