BackendBench
Coffee

Unravel โ€บ Java concepts โ€บ Collections and streams

Java language

Iterator and Iterable

An Iterator walks through a collection one element at a time (hasNext, next, remove).

Learn these first

At a glance

Mental model

A bookmark in a book: it knows where you are, can tell you whether there is another page, and moves forward one page at a time without you caring how the book is bound.

What happens, in order
  1. 1for (String s : list) is shorthand for getting list.iterator() and looping while (it.hasNext()) { String s = it.next(); ..}.
  2. 2To remove while looping, use the iterator itself: it.remove() after next()Removing through the collection during a for-each throws ConcurrentModificationException.
  3. 3To make your own class work in for-each, implement Iterable<T> and return an Iterator<T> from iterator()
  4. 4ListIterator can also go backwards and replace elements
Remember
Watch out
Calling it.remove() before next()Removing from the list inside for-eachCalling next() without hasNext()
Example (highlighted lines explain it)
import java.util.*;public class Range implements Iterable<Integer> {  private final int from, to;  Range(int from, int to) { this.from = from; this.to = to; }  @Override public Iterator<Integer> iterator() {    return new Iterator<>() {      int next = from;      public boolean hasNext() { return next < to; }      public Integer next() { return next++; }    };  }  static void dropNegatives(List<Integer> list) {    for (Iterator<Integer> it = list.iterator(); it.hasNext(); ) if (it.next() < 0) it.remove();  }}
  1. line 2 uses Iterable, the core of Iterator and Iterable
  2. line 5 uses Iterator, the core of Iterator and Iterable
  3. line 6 uses Iterator, the core of Iterator and Iterable
  4. line 8 uses hasNext, the core of Iterator and Iterable
  5. line 13 uses Iterator, the core of Iterator and Iterable
Read the full explanation (about 1 min)

An Iterator walks through a collection one element at a time (hasNext, next, remove). Anything implementing Iterable can be used in a for-each loop.

A mental model

A bookmark in a book: it knows where you are, can tell you whether there is another page, and moves forward one page at a time without you caring how the book is bound.

How it works

for (String s : list) is shorthand for getting list.iterator() and looping while (it.hasNext()) { String s = it.next(); ... }.

To remove while looping, use the iterator itself: it.remove() after next(). Removing through the collection during a for-each throws ConcurrentModificationException.

To make your own class work in for-each, implement Iterable<T> and return an Iterator<T> from iterator().

ListIterator can also go backwards and replace elements.

Going deeper

Iterators of the standard collections are fail-fast: they check a modification counter and throw as soon as they notice a change they did not make. This is a best-effort bug detector, not a guarantee for threads.

Iterators of concurrent collections are weakly consistent: they never throw, and may or may not show changes made after they were created.

Lazy iterators (read a file or database cursor line by line) need closing; wrap them in a Stream with onClose or in try-with-resources.

Under the hood

ArrayList.Itr stores a cursor, lastRet and an expectedModCount that it compares with the list's modCount on every next() and remove().

Common mistakes

  • Calling it.remove() before next().
  • Removing from the list inside for-each.
  • Calling next() without hasNext().

How Unravel recognises it

When you paste code, Unravel looks for these signs of iterator and iterable. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Frequently asked questions

What is Iterator and Iterable?

An Iterator walks through a collection one element at a time (hasNext, next, remove). Anything implementing Iterable can be used in a for-each loop.

What are the most common mistakes with Iterator and Iterable?

Calling it.remove() before next(). Removing from the list inside for-each. Calling next() without hasNext().

How can I see Iterator and Iterable in real code?

Paste your own Java into Unravel and it will point out where iterator and iterable appears, explain how it works at the detail level you choose, and draw the flow of the code around it.