Iterator
In short: An object used to go through the elements of a collection one after another, with no need to know the concrete internal implementation of the data structure.
In more detail: An iterator internally keeps track of the current position and typically offers two core operations: check whether another element follows, and retrieve the next element. This allows the same iteration code to be reused for very different data structures (list, set, map) — the “for-each” loop of many languages is usually just a convenient shorthand for working with an iterator.
In Depth
Without an iterator, any code that iterates over a collection would have to know its internal structure — for an array, that would be an index counter, for a linked list, following “next element” pointers, for a tree, a completely different traversal logic. The iterator hides this difference behind a unified interface, a classic example of abstraction.
iterator = list.createIterator()
while iterator.hasNext():
element = iterator.next()
process(element)Most modern languages offer a more convenient shorthand for this, which still uses an iterator internally:
for element in my_list: # uses an iterator under the hood
process(element)An important pitfall: modifying a collection while iterating over it (e.g. removing an element in the middle of the iteration) leads in many languages to a runtime error (“ConcurrentModificationException” in Java) or to unpredictable behaviour, because the iterator can no longer reliably reconcile its remembered position with the changed structure. For “remove while iterating”, many languages therefore offer an explicit remove() method directly ON the iterator, which safely handles this situation, instead of modifying the collection itself from outside.
An iterator is also fundamentally one-shot and forward-only — once you’ve reached the end, you have to request a new iterator from the collection to start again from the beginning; it doesn’t “remember” a reset state.
See also: Collections, For Loop