← Flutter & Dart

Dart Fundamentals

What's the difference between `List`, `Set`, and `Map` in Dart, and when should you use each?

Show answer — try answering out loud first

List is an ordered collection that allows duplicates (like an array). Set is a collection with no guaranteed order that doesn't allow duplicates. Map stores key-value pairs, where each key is unique. You choose based on whether you need order, uniqueness, or lookup by key.

  • List: elements in order, accessible by index (list[0]). Allows repeats. It's the most common.
  • Set: a set. It doesn't guarantee order and drops duplicates automatically. Perfect when all you care about is "is it there or not?" and you want to avoid repeats.
  • Map: a dictionary. Each value is stored under a unique key (map["name"]). Ideal for looking up data quickly by a key.

A performance detail: checking whether an element exists is fast in Set and Map (they use hashing), but in a List you have to walk through it.

void main() {
  // List: ordered, allows duplicates
  List<int> numbers = [1, 2, 2, 3];
  numbers.add(4);
  print(numbers); // [1, 2, 2, 3, 4]
  print(numbers[0]); // 1 (access by index)

  // Set: no duplicates
  Set<int> unique = {1, 2, 2, 3};
  print(unique); // {1, 2, 3} (the repeated 2 is dropped)
  print(unique.contains(2)); // true

  // Map: key-value
  Map<String, int> ages = {"Mike": 25, "Ana": 30};
  print(ages["Mike"]); // 25
  ages["Luis"] = 40; // add
  print(ages.keys); // (Mike, Ana, Luis)
  print(ages.values); // (25, 30, 40)

  // Trick: remove duplicates from a list by going through a Set
  List<int> withRepeats = [1, 1, 2, 3, 3];
  List<int> withoutRepeats = withRepeats.toSet().toList();
  print(withoutRepeats); // [1, 2, 3]
}

Accessing a key that doesn't exist in a Map and not handling the null. ages["DoesNotExist"] returns null, it doesn't throw an error. If you expected a value and don't check, you carry a null somewhere you didn't expect it. Use ages["key"] ?? defaultValue or containsKey.

"List is ordered and allows duplicates; I use it for sequences where order matters. Set doesn't allow duplicates and doesn't guarantee order; I use it when I only care about uniqueness or asking whether an element exists. Map stores key-value pairs with unique keys, ideal for lookup by key. A common trick is converting a list to a Set and back to a List to remove duplicates. Also, searching in a Set and Map is faster than in a List because they use hashing."

Quick challenge

What does this code print?

var s = {1, 2, 3};
var m = {};
print(s.runtimeType);
print(m.runtimeType);
See answer

s is a Set (roughly _Set<int>). But m with an empty {} is a Map, not a Set. In Dart, an empty {} defaults to a Map. If you want an empty Set you have to write <int>{} or Set<int>(). It's a classic trap.