Dart Iterator
last modified April 4, 2025
In Dart, the Iterator interface provides a way to access elements of a collection sequentially. It is fundamental to Dart's iteration mechanism.
The Iterator interface has two key methods: moveNext
and
current
. Most collections implement Iterable which provides an
iterator.
Basic Iterator Usage
This example shows the fundamental way to use an iterator manually.
void main() { var numbers = [1, 2, 3, 4, 5]; var iterator = numbers.iterator; while (iterator.moveNext()) { print(iterator.current); } }
We create an iterator from a list and use moveNext() to advance through elements. The current property gives the current element. This is how for-in loops work internally.
$ dart main.dart 1 2 3 4 5
Custom Iterator Implementation
This example demonstrates creating a custom class that implements Iterator.
class Countdown implements Iterator<int> { int _current = 5; @override int get current => _current; @override bool moveNext() { if (_current > 0) { _current--; return true; } return false; } } void main() { var countdown = Countdown(); while (countdown.moveNext()) { print(countdown.current); } }
We implement the Iterator interface with a countdown from 5 to 0. moveNext() decrements _current until it reaches 0. The current getter returns the value.
$ dart main.dart 4 3 2 1 0
Iterable with Iterator
This example shows how to create a custom Iterable class that provides an iterator.
class FibonacciSequence implements Iterable<int> { final int count; FibonacciSequence(this.count); @override Iterator<int> get iterator => _FibonacciIterator(count); } class _FibonacciIterator implements Iterator<int> { final int count; int _current = 0; int _next = 1; int _position = 0; _FibonacciIterator(this.count); @override int get current => _current; @override bool moveNext() { if (_position < count) { var newNext = _current + _next; _current = _next; _next = newNext; _position++; return true; } return false; } } void main() { var fib = FibonacciSequence(7); for (var num in fib) { print(num); } }
We create a Fibonacci sequence generator. The Iterable provides an iterator that generates numbers. This allows the class to be used in for-in loops.
$ dart main.dart 1 1 2 3 5 8 13
Iterator with Complex Objects
This example shows using an iterator with a collection of custom objects.
class Book { final String title; final String author; Book(this.title, this.author); @override String toString() => '$title by $author'; } class Library implements Iterable<Book> { final List<Book> _books = []; void add(Book book) => _books.add(book); @override Iterator<Book> get iterator => _books.iterator; } void main() { var library = Library(); library.add(Book('Dart in Action', 'Manning')); library.add(Book('Flutter in Action', 'Manning')); library.add(Book('Effective Dart', 'Google')); var iterator = library.iterator; while (iterator.moveNext()) { print(iterator.current); } }
We create a Library class that holds Books and implements Iterable. The iterator comes from the underlying List. This pattern is common in collection classes.
$ dart main.dart Dart in Action by Manning Flutter in Action by Manning Effective Dart by Google
Iterator Utilities
This example demonstrates useful iterator utilities like takeWhile and skipWhile.
void main() { var numbers = [1, 3, 5, 2, 4, 6, 8, 7]; var iterator = numbers.iterator; print('Numbers while odd:'); var oddIterator = numbers.takeWhile((n) => n.isOdd).iterator; while (oddIterator.moveNext()) { print(oddIterator.current); } print('\nNumbers after first even:'); var afterEven = numbers.skipWhile((n) => n.isOdd).iterator; while (afterEven.moveNext()) { print(afterEven.current); } }
We use takeWhile to get elements until a condition fails, and skipWhile to skip elements until a condition fails. These methods return new iterators.
$ dart main.dart Numbers while odd: 1 3 5 Numbers after first even: 2 4 6 8 7
Best Practices
- Prefer for-in: Use for-in loops rather than manual iteration when possible.
- Single-pass: Remember most iterators are single-pass only.
- Lazy evaluation: Iterators evaluate elements lazily when needed.
- Error handling: Check moveNext() before accessing current.
Source
This tutorial covered Dart's Iterator interface with practical examples showing basic usage, custom implementations, and common patterns.
Author
List all Dart tutorials.