Mastering Java's Iterator: Simplify Collection Traversal and Internals
This article explains Java's Iterator pattern, compares it with traditional loop approaches, shows how it abstracts collection traversal, details the Iterator interface methods, and walks through the internal ArrayList iterator implementation with code examples and diagrams.
Java provides an Iterator interface that standardizes how collections are traversed, allowing developers to iterate over any container without exposing its internal structure.
Before iterators, developers often used raw array loops or index‑based for‑loops on ArrayList, which required knowledge of the collection’s internal layout and tightly coupled access code to the data structure.
The Iterator pattern abstracts this traversal logic: the client interacts only with an iterator, issuing commands such as "next", "hasNext", or "remove", while the iterator maintains all internal state.
The java.util.Iterator interface defines three core methods: boolean hasNext() – checks if more elements are available. Object next() – returns the next element (requires casting to the desired type). void remove() – removes the element returned by the most recent next() call.
Typical usage looks like:
for (Iterator it = c.iterator(); it.hasNext(); ) {
Object o = it.next();
// do something with o
}In ArrayList, the iterator is implemented by an inner class Itr. The class holds three integer fields: int cursor – index of the next element. int lastRet – index of the element returned by the last next() call (initially -1). int expectedModCount – snapshot of the list’s modCount to detect concurrent modifications.
The hasNext() method simply checks cursor < size, as illustrated in the diagram above.
The next() implementation returns the element at cursor, updates cursor and lastRet, and performs bounds and concurrent‑modification checks:
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}The helper method checkForComodification() verifies that the list’s modCount matches expectedModCount, ensuring the iterator fails fast if the collection is structurally modified during iteration.
The remove() method delegates to ArrayList 's own removal logic, deleting the element at lastRet and updating modCount accordingly.
Understanding this internal iterator design helps developers write safer, more decoupled code and avoid common pitfalls such as ConcurrentModificationException when modifying a collection during traversal.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
JavaEdge
First‑line development experience at multiple leading tech firms; now a software architect at a Shanghai state‑owned enterprise and founder of Programming Yanxuan. Nearly 300k followers online; expertise in distributed system design, AIGC application development, and quantitative finance investing.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
