collections

Iterator vs ListIterator: Traversal & Modification

šŸ”¹ Iterator vs ListIterator (Deep Dive, Interview-Ready)

Java provides several ways to traverse collections, but Iterator and ListIterator are the most fundamental. Interviewers frequently ask about the differences between them to test your understanding of how different collection types are manipulated during iteration.


šŸ“Œ 1. Core Difference (One-Liner)

Iterator is a universal cursor used to traverse any Java Collection in a single forward direction, whereas ListIterator is a specialized cursor exclusive to List implementations that allows bi-directional traversal and element modification.


šŸ“Š 2. Detailed Comparison

FeatureIteratorListIterator
ApplicabilityWorks on Any Collection (List, Set, Queue)Works ONLY on List (ArrayList, LinkedList, etc.)
Traversal DirectionForward only (hasNext(), next())Bi-directional (hasPrevious(), previous())
Element ModificationāŒ Cannot replace or add elementsāœ… Supports set(E e) and add(E e)
Element Removalāœ… Supports remove()āœ… Supports remove()
Index AccessāŒ No index conceptāœ… Yes (nextIndex(), previousIndex())
Creation Methodcollection.iterator()list.listIterator()

šŸ“Œ 3. Safe Removal During Iteration

One of the most frequent trap questions in interviews is about removing elements while iterating.

āŒ The Wrong Way (ConcurrentModificationException)

If you try to remove an element using the collection's native remove() method while inside a for-each loop, Java will instantly crash.

List<String> names = new ArrayList<>(Arrays.asList("Alice", "Bob", "Charlie")); for (String name : names) { if (name.equals("Bob")) { names.remove(name); // šŸ’„ CRASH: ConcurrentModificationException } }

āœ… The Safe Way (Iterator.remove)

The only safe way to remove an element during traversal is by explicitly using the iterator's remove() method.

Iterator<String> iterator = names.iterator(); while (iterator.hasNext()) { String name = iterator.next(); if (name.equals("Bob")) { iterator.remove(); // āœ… Safe removal } }

šŸ‘‰ Why? The iterator maintains an internal counter (expectedModCount) to match the collection's state (modCount). Calling list.remove() changes the collection without telling the iterator, breaking the contract. Calling iterator.remove() safely updates both.


šŸ“Œ 4. The Power of ListIterator

Because a List has a guaranteed ordering (indices), ListIterator is vastly more powerful than a standard Iterator.

šŸ”ø 1. Bi-directional Traversal

You can traverse backward from the end of a list.

ListIterator<String> listIterator = names.listIterator(names.size()); // Start at the end while (listIterator.hasPrevious()) { System.out.println(listIterator.previous()); // Prints in reverse }

šŸ”ø 2. In-Place Replacement and Addition

Unlike a generic Iterator that can only delete, ListIterator lets you replace elements or insert brand new elements right where the cursor is currently resting.

ListIterator<String> it = names.listIterator(); while (it.hasNext()) { String name = it.next(); if (name.equals("Bob")) { it.set("Robert"); // āœļø Replaces "Bob" with "Robert" } else if (name.equals("Alice")) { it.add("Alex"); // āž• Inserts "Alex" immediately after "Alice" } }

šŸ“Œ 5. Why doesn't Iterator have an add() method?

A common follow-up question is: "Why does ListIterator have add(), but Iterator doesn't?"

šŸ‘‰ The Answer: Iterator is generic and must work for all collections, including Sets (like HashSet). A HashSet has no guaranteed order. Therefore, the concept of "inserting an element exactly at the current cursor position" makes no logical sense in a Set. Conversely, ListIterator only works on Lists, which are strictly ordered by index, making targeted additions and replacements perfectly logical.


šŸ”„ Interview Gold Statement

"Iterator is a universal, forward-only cursor for traversing any collection and is the only safe way to remove elements during iteration without triggering a ConcurrentModificationException. ListIterator, however, is exclusively designed for Lists, leveraging their ordered nature to provide powerful bi-directional traversal, index tracking, and in-place element addition and modification."


⚔ Final Verdict

  • āœ… Use Iterator for traversing Sets, Queues, or when you just need basic read/remove operations on a List.
  • šŸŽÆ Use ListIterator strictly when working with a List and you need to traverse backward, or safely insert/replace items dynamically during the loop.
Iterator vs ListIterator: Traversal & Modification | DevExCode