๐ Oops, I Looped It Again! — The Ultimate Java Loop Guide You Won't Forget
“I remember this question from one of my early interviews — I was just 2 years into Java and the interviewer asked, ‘Which loop do you prefer and why?’”
At first, I thought, “Duh! for-each is cleaner.” But then he grilled me with cases where it fails. ๐ต
That led me to explore all loop types, their powers, and their pitfalls.
Let’s deep-dive into every major Java loop with examples & real-world guidance so you'll never forget again.
๐ Loop Type #1: Classic For Loop — “The Old Reliable”
✅ When to Use:- You need an index
- You want to iterate in reverse
- You want full control over loop mechanics
List<String> names = List.of("A", "B", "C");
for (int i = 0; i < names.size(); i++) {
System.out.println(i + ": " + names.get(i));
}
๐ฅ Reverse + Removal Example:
List<String> items = new ArrayList<>(List.of("X", "Y", "Z"));
for (int i = items.size() - 1; i >= 0; i--) {
items.remove(i);
}
System.out.println(items); // [] ✅ Safe
❌ Common Pitfall:
for (int i = 0; i < list.size(); i++) {
list.remove(i); // ❌ May skip elements due to index shift
}
๐ต While reading about this, I had a doubt — “If this doesn't throw ConcurrentModificationException, why is it still bad?”
✅ Answer: Because removal shifts the elements left, so the loop skips over the next item.
๐ Loop Type #2: Enhanced ForEach Loop — “The Clean Reader with Boundaries”
✅ When to Use:- You want to read values only
- No need for index or mutation
for (String fruit : fruits) {
System.out.println(fruit);
}
❌ Bad Example:
for (String name : list) {
list.remove(name); // ❌ CME will occur
}
๐ฅ Behind the scenes: This uses an implicit iterator. Modifying the list causes CME.
๐ฌ My thought: “So if this is just syntax sugar for an iterator, why not use iterator directly and control it?”
๐ฅ Answer: Exactly! If you plan to remove or modify items, switch toIterator
.
๐ฅท Loop Type #3: Iterator — “The Safe Mutator Ninja”
✅ When to Use:- Need to remove elements safely
- No index required
Iterator<String> it = list.iterator();
while (it.hasNext()) {
if (it.next().equals("X")) {
it.remove(); // ✅ Safe!
}
}
๐ฅ Internal Magic:
modCount
tracks list changesexpectedModCount
is stored inside iterator- Mismatch = ๐ฃ
ConcurrentModificationException
Iterator<String> it = list.iterator();
while (it.hasNext()) {
if (it.next().equals("B")) {
list.remove("B"); // ❌ CME
}
}
๐ค I asked Myself “Why does iterator.remove() work but list.remove() doesn’t?”
✅ Answer: Because iterator updates bothmodCount
andexpectedModCount
in sync!
๐ Loop Type #4: ListIterator — “The Bi-directional Beast”
✅ When to Use:- Need to go forward AND backward
- Need to add/replace during iteration
ListIterator<String> it = list.listIterator();
while (it.hasNext()) {
if (it.next().equals("Cat")) {
it.add("Tiger"); // ✅ Adds after \"Cat\"
}
}
✅ Replace with set():
while (it.hasNext()) {
if (it.next().equals("Old")) {
it.set("New"); // ✅ Replace
}
}
๐ Reverse Loop:
ListIterator<String> it = list.listIterator(list.size());
while (it.hasPrevious()) {
System.out.println(it.previous());
}
๐ก I wondered: “Can’t we use iterator() and go reverse?”
❌ Answer: Nope! Only ListIterator supportshasPrevious()
+previous()
.
๐ง Loop Type #5: Stream forEach() — “The Stylish But Stubborn Streamer”
✅ When to Use:- Need short, clean, read-only loop
- Want to chain filter/map/forEach
list.stream()
.filter(item -> item.length() > 3)
.map(String::toUpperCase)
.forEach(System.out::println);
❌ Don't Mutate Inside:
list.forEach(item -> {
if (item.equals("B")) {
list.remove(item); // ❌ CME
}
});
๐คฏ I asked: “Even stream forEach doesn’t allow modification?!”
✅ Yes, because it uses internal iteration. You're not supposed to mutate the collection during streaming.
๐ง Final Summary: Which Loop to Use When?
Loop Type | Index | Remove | Add | Reverse | Modern? |
---|---|---|---|---|---|
For Loop | ✅ | ✅ | ✅ | ✅ | ❌ |
For-Each | ❌ | ❌ | ❌ | ❌ | ✅ |
Iterator | ❌ | ✅ | ❌ | ❌ | ⚠️ |
ListIterator | ✅ | ✅ | ✅ | ✅ | ✅ |
Stream.forEach | ❌ | ❌ | ❌ | ❌ | ✅✅ |
๐คน Wrapping Up — Loop Like a Legend
When someone again asks, “Which loop do you prefer?” — don’t just say “forEach is clean.” ๐
Instead, drop a mini-masterclass with examples, trade-offs, and the right loop for the job.
๐ Because Java isn’t just about writing code — it’s about knowing why something works the way it does.
๐ฃ If this helped or made you smile — do share, drop your feedback, and tell me:
๐งฉ “Which loop got you once in production or an interview?” ๐๐
Comments
Post a Comment