# Iterator Pattern

The `Iterator` design pattern is a well-known and often-used pattern. It allows us to access elements in a collection without the need to know about the underlying storage details. We get this functionality from an object known as an **iterator** of the collection.

Different languages support creating iterators when working with collections. Check out [this article](https://charlesmuchene.com/can-i-borrow-the-moved-iterator) for an example of using iterators in the Rust language. In the JVM land, a language like Java has the concept of a collections framework. In the framework, we find a `Set`, a `List`, and a `Deque` among other types. All these types define a [`Collection`](https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/util/Collection.html) of elements that can be iterated. Their difference lies in how elements are stored and retrieved.

All Java collections conform to the [`Iterable`](https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/lang/Iterable.html) interface. This interface requires that any object that conforms to it, provide an implementation that will return an instance of an [`Iterator`](https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/util/Iterator.html):

```java
public interface Iterator<E> {
    
    boolean hasNext();
    
    E next();

    ...
}
```

The idea behind this definition is that for any iterator, we can:

* Check if there's a next element in the iteration
    
* Ask for the next element
    

By combining these two operations, we can traverse any generic collection without consideration of how the elements are stored and for any number of elements.

> If we call `iterator.hasNext()` and it returns `false`, what happens if we call `iterator.next()`? 🤔

While we can directly invoke the above traversal methods to advance an iteration, most JVM languages offer iteration syntactic sugar that [decomposes](https://docs.oracle.com/javase/specs/jls/se20/html/jls-14.html#jls-14.14.2) to these calls on an `Iterator`. Let us consider the following example:

```kotlin
fun main() {
    val numbers = listOf(1, 2, 3, 4)
    
    for (number in numbers) {
        println(number)
    }
}
```

The [byte code](https://gist.github.com/charlesmuchene/61d868b41f28022f0d1747054b868d55#file-learningiterators-class-L35-L49) result of compiling the above snippet shows a couple of `INVOKEINTERFACE` calls to methods on the `Iterator` interface. Decompiling this byte code, we get the stripped-out listing below:

```java
List numbers = CollectionsKt.listOf(new Integer[]{1, 2, 3, 4});
Iterator var2 = numbers.iterator();

while(var2.hasNext()) {
  int number = ((Number)var2.next()).intValue();
  System.out.println(number);
}
```

We see that the compiler extracts an `Iterator` from our **numbers** collection and replaces the *for-loop* construct with a *while-loop*. It then invokes `hasNext()` to check the existence of the next element. If this returns true, a call to `next()` retrieves the next element in the collection and we act on it. These last two steps are executed `numbers.size()` times. This is the typical use case of the iterator pattern for built-in collection types. Let's look at a use case in Android.

## Iterating on Android Fragments

Android facilitates building UI by composing several standalone UI portions. When we create these modular UI portions, we bind them to a [Fragment](https://developer.android.com/guide/fragments) and add these fragment instances to an [Activity](https://developer.android.com/guide/components/activities/intro-activities).

The following snippet shows a method that retrieves ids of all fragments added to an Activity.

```kotlin
class SomeActivity : AppCompatActivity() {

    fun fragmentIds(): List<Int> = 
        supportFragmentManager
            .fragments
            .map(Fragment::getId)
}
```

It might not be obvious that the iterator pattern is in use here. But if we dig into the `map(...)` call, we find that it is an [extension](https://github.com/JetBrains/kotlin/blob/924c28507067cbfbf78a6509ea89eabe496e34ca/libraries/stdlib/common/src/generated/_Collections.kt#L1542-L1550) function that iterates and maps elements in an `Iterable` according to the given transform function. There are a couple more such extensions that add operators applicable to the implementations of `Iterable`.

As seen, we are oblivious to how the fragments are stored in the [FragmentManager](https://developer.android.com/guide/fragments/fragmentmanager). Our algorithm receives each added fragment, extracts its id, and adds this id to a list of fragment ids. This operation is powered by the iterator pattern.

## Countries of Africa

As a final example, let's look at a [Compose desktop](https://github.com/charlesmuchene/african-countries) app with a custom implementation of the iterator pattern.

![https://ontheworldmap.com/africa/africa-political-map.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1683399652563/734d3401-344e-46b3-b4b7-7761967b6388.jpeg align="center")

[https://ontheworldmap.com/africa/africa-political-map.jpg](https://ontheworldmap.com/africa/africa-political-map.jpg)

The African continent has 54 countries. In our sample code, each country is represented by a couple of properties such as its *name*, *flag* etc. We model the continent using a type, `Africa`, as shown below. By conforming to `Iterable`, we can iterate through all constituent countries of `Africa`. We can achieve this by defining an internal iterator, `CountryIterator`, and returning its instance for a call to `iterator()` on `Africa`. In our implementation, we maintain the state of the iteration using the `nextIndex` property.

```kotlin
class Africa(private val countries: Countries) : Iterable<Country> {

    override fun iterator(): Iterator<Country> = CountryIterator(countries)

    private class CountryIterator(private val countries: Countries) : Iterator<Country> {

        private var nextIndex = if (countries.isEmpty()) -1 else 0

        override fun hasNext(): Boolean = nextIndex in countries.indices

        override fun next(): Country {
            if (!hasNext()) throw NoSuchElementException("No more countries")
            return countries[nextIndex].also {
                nextIndex += 1
            }
        }
    }
}
```

We then iterate through all countries, adding a corresponding [`CountryRow`](https://github.com/charlesmuchene/african-countries/blob/main/src/jvmMain/kotlin/UI.kt#L64-L78) item in the [`LazyColumn`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyColumn(androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.Alignment.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)) for each country.

```kotlin
LazyColumn {
    val iterator = africa.iterator()
    while (iterator.hasNext()) {
        val country = iterator.next()
        item(key = country.code) {
            CountryRow(country = country)
        }
    }
}
```

This creates the country UI listing as shown:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1683437827954/e559c7ad-fdf9-45e3-bc4d-2ed024c16d3b.png align="center")

Get the full source on [GitHub](https://github.com/charlesmuchene/african-countries).

## Conclusion

We can iterate over a collection multiple times, create iterators that mutate the collection, iterate an ordered collection backward and so much more. The iterator pattern is a welcome addition to our set of patterns for software design.

Happy coding!
