Skip to main content

🎒 Java Loops: Fun, Fear, and ForEach() Fails

πŸŒ€ 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
✅ Good Example:
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
✅ Good Example:
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 to Iterator.

πŸ₯· Loop Type #3: Iterator — “The Safe Mutator Ninja”

✅ When to Use:
  • Need to remove elements safely
  • No index required
✅ Safe Removal Example:
Iterator<String> it = list.iterator();

while (it.hasNext()) {

    if (it.next().equals("X")) {

        it.remove(); // ✅ Safe!

    }

}

πŸ”₯ Internal Magic:
  • modCount tracks list changes
  • expectedModCount is stored inside iterator
  • Mismatch = πŸ’£ ConcurrentModificationException
❌ Unsafe Removal Example:
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 both modCount and expectedModCount 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
✅ Add While Iterating:
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 supports hasPrevious() + 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
✅ Good Use:
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 TypeIndexRemoveAddReverseModern?
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

Popular posts from this blog

🐱 Tomcat vs ⚡ Netty – Which One Should You Use?

🐱 Tomcat vs ⚡ Netty – Which One Should You Use? So recently I got curious about this too πŸ€”. Everywhere in Spring Boot tutorials we see Tomcat . Then suddenly while exploring Spring WebFlux , the name Netty pops up. And I was like – “Wait, who’s this Netty guy trying to replace Tomcat?” πŸ˜… Let’s break it down with real-time examples , icons , and fun comparisons . 🐱 Tomcat – The Traditional Web Server Type: Servlet Container (blocking I/O) World: Used with Spring MVC Style: Thread-per-request model πŸ‘©‍πŸ’» Pros: Stable, widely used, battle-tested Cons: Struggles with huge concurrent connections πŸ‘‰ Example in real life: Tomcat is like a restaurant with fixed waiters 🍴. - Each customer = one thread/waiter - If too many customers come in at once → waiters run out → customers wait outside πŸšͺ ⚡ Netty – The Reactive Rockstar Type: Asynchronous Event-Driven Network Framework World: Default for Spring WebFlux Style: Event-lo...

🎭 Spring’s Secret: Why @Transactional & Friends Betray You Silently

πŸ’‘ Lesson Learned — Not a Prod Bug, But a Real Pain No, this wasn’t a production outage. Nobody screamed at me. But I sat for 3 hours wondering: “Why the heck is my @Transactional not rolling back!?” 😡‍πŸ’« “Why is Redis cache not working?” 🀯 Turned out, the issue was one silent villain: 🧱 Self-invocation 🀷 What Is @Transactional ? If you're new: @Transactional = Tells Spring to start a DB transaction when a method is called. It’ll commit if everything’s okay. It’ll rollback if something fails. 🧠 Think of it like wrapping your code in: try { beginTransaction(); // your logic commit(); } catch(Exception e) { rollback(); } πŸ•΅️ Real-Life Analogy — The Gateway Community 🏘️ Let me tell you about my society — it has a strict watchman at the gate. Here’s how it works: πŸ›‚ Watchman = Spring Proxy 🏠 Your apartment = Your service class πŸšͺ Your room = A method inside that class πŸƒ Scenario 1: Outsider Visits Your friend from outside...

🌟 My Journey – From Zero to Senior Java Tech Lead 🌟

 There’s one thing I truly believe… If I can become a Java developer, then anyone in the world can. πŸ’― Sounds crazy? Let me take you back. πŸ•“ Back in 2015… I had zero coding knowledge . Not just that — I had no interest in coding either. But life has its own plans. In 2016, I got a chance to move to Bangalore and joined a Java course at a training center. That’s where it all started — Every day, every session made me feel like: "Ohhh! Even I can be a developer!" That course didn’t just teach Java — it gave me confidence . πŸ§ͺ Two Life-Changing Incidents 1️⃣ The Interview That Wasn't Planned Halfway through my course, I had to urgently travel to Chennai to donate blood to a family member. After that emotional rollercoaster, I found myself reflecting on my skills and the future. The next day, as I was preparing for my move to Bangalore to complete the remaining four months of my course, I randomly thought — "Let me test my skills... let me just see...