Lists, sets and maps

Dart · Essentials · 12 min

Collections hold almost all app data, and collection-if/for is how Flutter builds lists of widgets.

Dart's core collections:

  • List<T> — ordered, zero-indexed: var nums = [1, 2, 3];.
  • Set<T> — unique items: var tags = {'dart', 'flutter'};.
  • Map<K, V> — key/value pairs: var ages = {'ana': 31, 'bo': 25};.

An empty {} is a Map; write <String>{} for an empty Set. Type arguments can be explicit: <int>[].

Lists support add, addAll, insert, removeAt, length, first, last, contains, indexOf, sort. Out-of-range indexing throws a RangeError. Map lookup ages['zoe'] returns null (the value type becomes nullable); use containsKey, putIfAbsent or update(key, f, ifAbsent: ...). Iterate maps with for (final MapEntry(:key, :value) in ages.entries) or ages.forEach.

Collection literals have special syntax:

  • Spread: [...a, ...b], and null-aware ...?maybeList.
  • Collection if: [ 'home', if (loggedIn) 'profile' ].
  • Collection for: [for (final n in nums) n * n].

This lets Flutter build widget lists declaratively: children: [Header(), if (showBanner) Banner(), for (final m in messages) Tile(m)].

Collections are mutable unless created const or with List.unmodifiable. A final variable can still have its list contents changed; only reassignment is blocked.

Example

void main() {
  final fruits = ['apple', 'pear'];
  fruits.add('kiwi');                 // final list, mutable contents
  print(fruits.length);               // 3

  final emptySet = <String>{};        // {} alone would be a Map
  emptySet.addAll(['a', 'a', 'b']);
  print(emptySet);                    // {a, b}

  final stock = {'apple': 3, 'pear': 0};
  stock.update('kiwi', (n) => n + 1, ifAbsent: () => 1);
  print(stock['plum']);               // null
  print(stock);                       // {apple: 3, pear: 0, kiwi: 1}

  const showAll = false;
  final menu = [
    'home',
    if (showAll) 'admin',
    for (final f in fruits) f.toUpperCase(),
  ];
  print(menu);                        // [home, APPLE, PEAR, KIWI]
}

Remember

  • [] List, {a, b} Set, {k: v} Map; {} alone is a Map
  • Collection if/for and spread ... build lists declaratively
  • Map lookup returns a nullable value

Watch out for

  • Declaring var s = {}; expecting a Set and getting a Map<dynamic, dynamic>.

Check yourself

  1. What does `[1, if (false) 2, for (var i in [3, 4]) i * 2]` produce?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: dart.dev/language/collections