Loops in Java: for, while and do-while
Every looping construct in Java, when each one fits, and how break, continue and labels change the flow.
-
Java Basics
- Introduction to Java
- Setting Up Java and Writing Your First Program
- Variables, Data Types and Literals in Java
- Type Casting and Type Conversion in Java
- Operators and Expressions in Java
- Input and Output in Java
- Comments, Keywords and Naming Conventions in Java
- Control Flow in Java: if, else and switch
- Loops in Java: for, while and do-while
- Methods
- Arrays and Strings
-
OOP
- Classes and Objects in Java
- Constructors in Java
- The this Keyword in Java
- The static Keyword in Java
- Encapsulation in Java
- Access Modifiers in Java
- Inheritance in Java
- Method Overriding and super in Java
- Polymorphism in Java
- Abstraction, Abstract Classes and Interfaces in Java
- Composition, Aggregation and Association in Java
- The Object Lifecycle in Java
- Core Java
- Exception Handling
-
Collections
- The Java Collections Framework
- List in Java: ArrayList, LinkedList, Vector and Stack
- Set in Java: HashSet, LinkedHashSet and TreeSet
- Map in Java: HashMap, LinkedHashMap and TreeMap
- How HashMap Works Internally in Java
- Queue and Deque in Java: ArrayDeque and PriorityQueue
- Iterators in Java
- Comparable and Comparator in Java
- Collections Utilities and Choosing the Right Collection
- Generics
- Java 8+
- Stream API
- Date and Time
- File and I/O
-
Multithreading
- Threads in Java: Processes, Runnable and Thread
- Thread Lifecycle in Java
- Synchronization in Java: synchronized and volatile
- Locks and Atomic Classes in Java
- Race Conditions and Deadlocks in Java
- The Executor Framework and Thread Pools in Java
- Future and CompletableFuture in Java
- Concurrent Collections in Java
- The Java Memory Model
- JVM and Memory
- Advanced Java
- Networking
- JDBC
- Testing
Why loops exist
A loop repeats a block while a condition holds. Choosing the right one is mostly a question of what you know before the loop starts.
The for loop
for (int i = 1; i <= 5; i++) {
System.out.println("Row " + i);
}The three parts run in a fixed order: the initialiser once, then the condition before every pass, then the update after every pass. Use a for loop when the number of iterations is known or the index itself is needed.
The enhanced for loop
int[] marks = {45, 78, 62, 91};
int total = 0;
for (int mark : marks) {
total += mark;
}
System.out.println("Total: " + total);It reads over arrays and anything implementing Iterable. There is no index, no bounds arithmetic and therefore no off by one error. Prefer it whenever the index is not needed.
The loop variable is a copy. Assigning tomarkinside the loop changes nothing in the array. To modify elements you need an indexedforloop.
The while loop
int balance = 1000;
int months = 0;
while (balance > 0) {
balance -= 250;
months++;
}
System.out.println("Months: " + months);Use while when the number of repetitions depends on something discovered during the loop, such as reading until the input runs out.
The do-while loop
Scanner in = new Scanner(System.in);
int choice;
do {
System.out.print("Choose 1 to 3: ");
choice = Integer.parseInt(in.nextLine().trim());
} while (choice < 1 || choice > 3);The condition is tested after the body, so the body always runs at least once. Menus and prompt loops are the natural fit. Note the required semicolon after the condition.
Comparing the loops
| Loop | Condition tested | Minimum passes | Use when |
|---|---|---|---|
for | Before the body | 0 | The count is known, or the index is needed |
enhanced for | Before the body | 0 | Reading every element in order |
while | Before the body | 0 | Repeating until something becomes true |
do-while | After the body | 1 | The body must run at least once |
break and continue
for (int n = 1; n <= 10; n++) {
if (n % 2 == 0) {
continue; // skip the rest of this pass
}
if (n > 7) {
break; // leave the loop entirely
}
System.out.print(n + " "); // 1 3 5 7
}Labelled break
int[][] grid = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int target = 5;
search:
for (int row = 0; row < grid.length; row++) {
for (int col = 0; col < grid[row].length; col++) {
if (grid[row][col] == target) {
System.out.println("Found at " + row + "," + col);
break search; // exits both loops
}
}
}An unlabelled break leaves only the innermost loop. A label is the clean way out of nested loops, and it is far better than a flag variable.
return inside a loop
return leaves the whole method immediately, loops included. Extracting a search into its own method and returning the result directly is usually clearer than break plus a result variable.
Common mistakes
- Using
<=witharray.lengthand running past the last index. - Forgetting to change the condition variable, producing an infinite loop.
- Placing a semicolon straight after
for (...), which makes an empty body. - Removing from a collection inside an enhanced
forloop, which throwsConcurrentModificationException. Use an explicitIteratororremoveIf. - Declaring the loop counter outside the loop when it is not needed afterwards.
Best practices
- Prefer the enhanced
forloop unless the index is genuinely required. - Keep loop bodies short; extract the work into a method with a name.
- Avoid changing the loop counter inside the body.
- For transforming or filtering a collection, consider the Stream API instead, which states the intent rather than the mechanics.
Practice
- Print the multiplication table of 7 using each of the three loop forms and compare readability.
- What does
for (int i = 0; i < 5; i++);followed by a block actually do? - Write a loop that finds the first number above 1000 divisible by both 13 and 17.
- Explain why removing an element inside an enhanced
forloop fails, and show two correct alternatives. - Rewrite a labelled
breaksearch as a separate method that returns the position.
Conclusion
Pick the loop that matches what you know in advance, prefer the enhanced form when you only need the elements, and reach for a label rather than a flag when leaving nested loops.