Skip to main content

Dart Collections

Collections are one of the most fundamental parts of every Dart program. Whether you are building a Flutter UI, writing a CLI tool, or processing data from an API, you will use collections constantly.

This section covers every collection type in the Dart core library and the dart:collection package — with complete method references, diagrams, real-world examples, and performance analysis.


What Is a Collection?

A collection is an object that groups multiple elements into a single unit. Collections let you store, retrieve, manipulate, and iterate over groups of values.

In Dart, all standard collections implement the Iterable<E> interface (except Map, which has a separate hierarchy). This means they share a rich set of common methods like map(), where(), fold(), any(), and every().

// Every collection can be iterated
List<int> list = [1, 2, 3];
Set<int> set = {1, 2, 3};
// Map is iterated via .entries, .keys, or .values
Map<String, int> map = {'a': 1, 'b': 2};

for (var x in list) print(x);
for (var x in set) print(x);
for (var e in map.entries) print('${e.key}: ${e.value}');

Collection Hierarchy

note

Map<K, V> does not implement Iterable. It has its own separate hierarchy but provides Iterable views via .keys, .values, and .entries.


The Two Roots: Iterable vs Map

FeatureIterable<E>Map<K, V>
Element typeSingle type EKey K + Value V
Iterationfor (var x in collection)for (var e in map.entries)
AccessBy index or orderBy key
Common subtypesList, Set, Queue, LinkedListHashMap, LinkedHashMap, SplayTreeMap
Shared methodsmap(), where(), fold(), any(), every()map(), forEach(), putIfAbsent()

Collection Categories

1. Sequences (Ordered, Indexed)

Collections where elements have a defined position and can be accessed by index.

TypeNotes
List<E>The most common. Growable or fixed-length.
Queue<E>Efficient add/remove at both ends (FIFO/LIFO).
DoubleLinkedQueue<E>Queue backed by a doubly-linked list.
LinkedList<E>Doubly-linked list with direct node access.

2. Sets (Unique Elements)

Collections that guarantee no duplicate elements.

TypeOrdered?Notes
Set<E>No (default: LinkedHashSet)General-purpose unique collection.
HashSet<E>NoFastest lookup; no order guarantee.
LinkedHashSet<E>Insertion orderDefault Set literal implementation.
SplayTreeSet<E>SortedSelf-balancing BST; always sorted.

3. Maps (Key-Value Pairs)

Collections of key-value associations where each key is unique.

TypeOrdered?Notes
Map<K, V>DependsAbstract; default is LinkedHashMap.
HashMap<K, V>NoFastest lookup; no order.
LinkedHashMap<K, V>Insertion orderDefault {} literal.
SplayTreeMap<K, V>Sorted by keyAlways sorted; good for range queries.

Complete Comparison Table

CollectionOrderedUniqueKey/ValueSortedGrowableImportTypical Use
List<E>coreOrdered items, indexable, most common
Set<E>⚠️ (insertion)coreUnique items, fast membership test
Map<K,V>⚠️ (insertion)Keys ✅coreKey-value pairs, lookups
Queue<E>dart:collectionFIFO/LIFO operations
DoubleLinkedQueue<E>dart:collectionEfficient double-ended queue
LinkedList<E>dart:collectionO(1) insert/remove with node refs
HashMap<K,V>Keys ✅dart:collectionFastest map lookups
LinkedHashMap<K,V>✅ (insertion)Keys ✅dart:collectionDefault Map literal
SplayTreeMap<K,V>✅ (sorted)Keys ✅dart:collectionSorted keys, range queries
HashSet<E>dart:collectionFastest set operations
LinkedHashSet<E>✅ (insertion)dart:collectionDefault Set literal
SplayTreeSet<E>✅ (sorted)dart:collectionSorted unique elements
tip

When in doubt, start with List, Set, or Map. Reach for specialised types only when you have a concrete reason (ordering, sorting, performance).


Collection Packages

dart:core (built-in — always available)

// No import needed
List<String> names = ['Alice', 'Bob'];
Set<int> ids = {1, 2, 3};
Map<String, int> scores = {'Alice': 95};

Includes: List, Set, Map, Iterable, Iterator

dart:collection

import 'dart:collection';

Queue<int> queue = Queue();
DoubleLinkedQueue<int> dlq = DoubleLinkedQueue();
LinkedList<MyEntry> ll = LinkedList();
HashMap<String, int> hm = HashMap();
LinkedHashMap<String, int> lhm = LinkedHashMap();
SplayTreeMap<String, int> stm = SplayTreeMap();
HashSet<int> hs = HashSet();
LinkedHashSet<int> lhs = LinkedHashSet();
SplayTreeSet<int> sts = SplayTreeSet();

package:collection (pub.dev)

Extends the standard library with powerful utilities.

# pubspec.yaml
dependencies:
collection: ^1.18.0
import 'package:collection/collection.dart';

// Equality helpers
final eq = ListEquality();
eq.equals([1, 2, 3], [1, 2, 3]); // true

// groupBy
final grouped = groupBy([1, 2, 3, 4], (n) => n.isEven ? 'even' : 'odd');
// {odd: [1, 3], even: [2, 4]}

// PriorityQueue
final pq = PriorityQueue<int>((a, b) => a.compareTo(b));
pq.add(5); pq.add(1); pq.add(3);
print(pq.removeFirst()); // 1

Choosing at a Glance


Key Concepts

Lazy vs Eager Evaluation

Most Iterable methods (like map(), where(), expand()) return lazy iterables — no computation happens until you consume the result.

var lazy = [1, 2, 3, 4, 5]
.where((n) => n.isOdd) // no work yet
.map((n) => n * 10); // no work yet

// Work happens HERE:
for (var n in lazy) print(n); // 10, 30, 50

// Or force it to a concrete collection:
var list = lazy.toList(); // [10, 30, 50]
var set = lazy.toSet(); // {10, 30, 50}

Mutability

TermMeaning
const collectionCompile-time constant; deeply immutable
final collectionVariable cannot be reassigned; contents can still change
List.unmodifiable()Runtime-immutable wrapper; throws on mutation
Growable ListDefault; elements can be added/removed
Fixed-length ListList.filled(n, val); length cannot change

Quick Syntax Reference

// List literal
var list = [1, 2, 3];
List<int> typed = <int>[1, 2, 3];

// Set literal
var set = {1, 2, 3};
Set<int> typedSet = <int>{1, 2, 3};
var empty = <int>{}; // ← NOT {} which is an empty Map!

// Map literal
var map = {'key': 'value'};
Map<String, int> ages = {'Alice': 30, 'Bob': 25};
var emptyMap = <String, int>{};

// Collection if / for / spread
var extended = [
...list,
if (true) 4,
for (var i = 5; i <= 6; i++) i,
];
// [1, 2, 3, 4, 5, 6]

Section Navigation

Explore every collection type in depth:

PageDescription
Iterable<E>The foundation of all collections
List<E>Ordered, indexable, most common
Set<E>Unique elements
Map<K,V>Key-value pairs
Queue<E>FIFO/LIFO queue
DoubleLinkedQueue<E>Doubly-linked queue
LinkedList<E>Node-based linked list
HashMap<K,V>Unordered, fastest map
LinkedHashMap<K,V>Insertion-ordered map
SplayTreeMap<K,V>Sorted map
HashSet<E>Unordered, fastest set
LinkedHashSet<E>Insertion-ordered set
SplayTreeSet<E>Sorted set
Unmodifiable CollectionsImmutability in Dart
Collection Literals[], {}, spread, if, for
Collection OperatorsSpread, cascade, null-aware
Collection UtilitiesIterable methods, generators
Collection EqualityDeepCollectionEquality and more
Choosing the Right CollectionDecision guide
Performance & ComplexityBig-O reference
Common PatternsGrouping, sorting, chunking…
Common MistakesPitfalls to avoid
Best PracticesProfessional recommendations