Common Collection Mistakes
Avoid these common pitfalls when working with Dart collections.
1. Modifying a Collection While Iterating
❌ Bad Code
final numbers = [1, 2, 3, 4, 5];
for (final n in numbers) {
if (n.isEven) {
numbers.remove(n); // Throws ConcurrentModificationError!
}
}
✅ Solution
Use removeWhere() or iterate over a shallow copy:
// Option A: removeWhere
numbers.removeWhere((n) => n.isEven);
// Option B: Shallow copy iteration
for (final n in [...numbers]) {
if (n.isEven) numbers.remove(n);
}
2. Using {} Intending to Create a Set
❌ Bad Code
final mySet = {}; // Creates a Map<dynamic, dynamic>, NOT a Set!
print(mySet.runtimeType); // _Map<dynamic, dynamic>
✅ Solution
final mySet = <String>{}; // Explicit type parameter
final set2 = <int>{1, 2, 3};
3. Assuming List.contains() is Fast
❌ Bad Code
final hugeList = List.generate(100000, (i) => i);
// O(n) scan every single check - very slow in loops!
for (var i = 0; i < 1000; i++) {
if (hugeList.contains(i)) { ... }
}
✅ Solution
Convert to a Set for O(1) checks:
final hugeSet = hugeList.toSet();
for (var i = 0; i < 1000; i++) {
if (hugeSet.contains(i)) { ... }
}
4. Misunderstanding List.filled() Reference Sharing
❌ Bad Code
// All 3 elements point to the SAME List instance!
final grid = List.filled(3, <int>[]);
grid[0].add(99);
print(grid); // [[99], [99], [99]] - unexpected mutation!
✅ Solution
Use List.generate() to produce fresh instances:
final grid = List.generate(3, (_) => <int>[]);
grid[0].add(99);
print(grid); // [[99], [], []]
5. Expecting Equality (==) to Check Collection Contents
❌ Bad Code
final listA = [1, 2, 3];
final listB = [1, 2, 3];
if (listA == listB) {
// Never executed! Reference comparison fails.
}
✅ Solution
Use package:collection:
import 'package:collection/collection.dart';
if (const ListEquality().equals(listA, listB)) {
// Executed successfully
}
6. Null Safety Pitfalls with Map Lookups
❌ Bad Code
final Map<String, int> scores = {'Alice': 100};
int bobScore = scores['Bob']!; // Throws Null check operator used on a null value!
✅ Solution
int bobScore = scores['Bob'] ?? 0;
// Or test existence
if (scores.containsKey('Bob')) {
print(scores['Bob']);
}
Summary
- Am I mutating a list inside a
for-inloop? (UseremoveWhere) - Did I write
{}expecting aSet? (Use<T>{}) - Am I using
List.containsinside a tight loop? (Convert toSet) - Did I create nested objects with
List.filled? (UseList.generate) - Am I comparing collections with
==? (Usepackage:collection)