Java Collections
Iterator
Complete lesson for Iterator using LEARNCODEGURU’s 6-level learning model — from basics to advanced practice, with Java OOP and Collections where relevant.
Basics — Iterator
Section: Java Collections. Iterator, ListIterator, fail-fast, forEachRemaining, and ConcurrentModificationException.
Iterator is a cursor
Iterable.iterator()returns anIterator. Enhanced for is compiled to this loop.hasNext()/next()are the core.remove()removes the last element returned bynext()— optional operation.- Calling
next()withouthasNext()throwsNoSuchElementException. Callingremove()twice withoutnext()throwsIllegalStateException.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteratorBasics {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("keep");
list.add("drop");
list.add("keep");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
if (it.next().equals("drop")) {
it.remove();
}
}
System.out.println(list);
}
} Iterator vs ListIterator vs for-each
| API | Direction | Can set/add? | Safe remove? |
|---|---|---|---|
Iterator | Forward | No | remove() only |
ListIterator | Both (hasPrevious) | set / add | Yes |
| for-each | Forward | No | No — CME if you mutate |
forEachRemaining (Java 8) | Rest of cursor | No | Depends on iterator |
ListIterator extras
list.listIterator()orlistIterator(index).nextIndex()/previousIndex()support algorithms that need positions.set(e)replaces the last element returned.add(e)inserts before the implicit next.
Advanced — Iterator
Fail-fast, weakly consistent, Spliterator
ArrayList/HashMapiterators incrementmodCount. A mismatch throwsConcurrentModificationException— even on one thread.- This is not a lock. Two threads mutating a HashMap can still corrupt it without always seeing CME.
ConcurrentHashMap/ConcurrentLinkedQueueiterators are weakly consistent: they reflect some but not necessarily all concurrent updates, and they do not throw CME.CopyOnWriteArrayListiterator is a snapshot —removeon the iterator is unsupported.- Streams use
Spliterator(splitable iterator) for parallel decomposition.iterator()andspliterator()both come fromIterable.
Tricky Interview Points
Q1) How do you remove while iterating a List?
Answer Use Iterator.remove, ListIterator.remove, removeIf, or iterate indexes backward. Do not list.remove inside for-each.
Q2) What is fail-fast?
Answer The iterator detects that the collection’s modCount changed (structural change) and throws ConcurrentModificationException.
Q3) Iterator vs ListIterator?
Answer ListIterator is list-only, bidirectional, and can set/add. Iterator is the general Collection cursor.
Q4) Why does for-each throw CME when you add?
Answer for-each uses an Iterator. add is a structural change not done through that iterator.
Q5) Can you iterate a Map with Iterator?
Answer Yes — map.entrySet().iterator(), or keySet()/values(). Directly on Map there is no iterator() because Map is not a Collection.
Q6) Is ConcurrentModificationException guaranteed?
Answer No. It is fail-fast best effort. ConcurrentHashMap will not throw it for typical concurrent writes.
Simple Programs
ListIterator reverse print and set
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListIteratorDemo {
public static void main(String[] args) {
List<String> words = new ArrayList<>();
words.add("one");
words.add("two");
words.add("three");
ListIterator<String> it = words.listIterator(words.size());
while (it.hasPrevious()) {
String w = it.previous();
if (w.equals("two")) it.set("TWO");
System.out.println(w);
}
System.out.println(words);
}
} Problem Solving Tricks
removeIfis clearer than a manual iterator for predicate deletes.- When teaching CME, mutate in for-each on purpose once so the stack trace is familiar.
- For maps, iterate
entrySet— not keys thenget. Iterator.forEachRemaining(Consumer)is handy after you already consumed a prefix.- Do not store an iterator and reuse it after the collection changes.
Practice Programs List
- Delete every string shorter than 3 using an Iterator.
- Use ListIterator to insert
"x"before each"a". - Reproduce CME, then fix the same loop.
- Iterate a
HashMapwithentrySet().iterator()and remove keys starting with_. - Write a method that returns an
Iteratorover 1..n without storing the whole list (custom Iterator).