โ† Back to Design Patterns
๐Ÿ”„
Behavioral

Iterator

Provides a way to sequentially access elements of a collection without exposing its underlying representation.

The Problem

A collection has a complex internal structure (tree, graph, ring buffer). You want to iterate over it without exposing how the data is stored.

How It Works

  • โ€บSeparates traversal logic from the collection class
  • โ€บSupports multiple simultaneous independent traversals of the same collection
  • โ€บEnables a unified for-in / for-of interface across all collections
  • โ€บLazy iterators (Kotlin Sequences, Python generators) compute elements on demand
  • โ€บInternal iterator hides the loop; external iterator gives the caller control

When to Use

โœ“Custom collections that need to support for-in/for-of loops
โœ“When you need multiple traversal strategies for the same collection
โœ“Hiding complex traversal logic (tree traversal, pagination)
โœ“Lazy sequences where computing all elements upfront is expensive

Real-World Examples

๐ŸŽ
iOS

IteratorProtocol + Sequence, IndexingIterator, for-in on any Collection type

๐Ÿค–
Android

Iterable<T>, Kotlin Sequences for lazy evaluation, Cursor for database rows

๐ŸŒ
Web

Symbol.iterator, Generator functions (function*), built-in Array/Map/Set iterators

Code Examples

Swift
struct Countdown: Sequence {
    let from: Int

    func makeIterator() -> CountdownIterator {
        CountdownIterator(current: from)
    }

    struct CountdownIterator: IteratorProtocol {
        var current: Int
        mutating func next() -> Int? {
            guard current >= 0 else { return nil }
            defer { current -= 1 }
            return current
        }
    }
}

let countdown = Countdown(from: 5)
for n in countdown { print(n) }  // 5, 4, 3, 2, 1, 0

// Works with all Sequence methods
print(countdown.contains(3))      // true
print(Array(countdown))           // [5, 4, 3, 2, 1, 0]