Dart HashMap
last modified April 4, 2025
In Dart, HashMap is an unordered collection of key-value pairs. It provides fast lookup, addition, and deletion of entries based on keys.
HashMap implements the Map interface and uses hash tables for storage. Keys must
have consistent Object.==
and Object.hashCode
implementations.
Creating a HashMap
The simplest way to create a HashMap is using the constructor.
import 'dart:collection'; void main() { var capitals = HashMap<String, String>(); capitals['USA'] = 'Washington'; capitals['Japan'] = 'Tokyo'; capitals['France'] = 'Paris'; print(capitals); }
We create a HashMap of country-capital pairs. The generic types specify that both keys and values are Strings. We add entries using the [] operator.
$ dart main.dart {USA: Washington, France: Paris, Japan: Tokyo}
HashMap from Iterable
We can create a HashMap from an existing Iterable using HashMap.fromIterable.
import 'dart:collection'; void main() { var fruits = ['apple', 'banana', 'orange']; var fruitMap = HashMap.fromIterable(fruits, key: (item) => item, value: (item) => item.length); print(fruitMap); }
This creates a HashMap where fruits are keys and their lengths are values. The key and value parameters transform each element during creation.
$ dart main.dart {orange: 6, banana: 6, apple: 5}
Checking Contents
HashMap provides methods to check for keys, values, and empty state.
import 'dart:collection'; void main() { var scores = HashMap<String, int>(); scores['Alice'] = 90; scores['Bob'] = 85; scores['Charlie'] = 95; print(scores.containsKey('Alice')); // true print(scores.containsValue(100)); // false print(scores.isEmpty); // false print(scores.length); // 3 }
We check various properties of the HashMap. Note that containsKey is O(1) while containsValue is O(n) in complexity.
$ dart main.dart true false false 3
Updating Values
HashMap provides several ways to update values, including update and putIfAbsent.
import 'dart:collection'; void main() { var inventory = HashMap<String, int>(); inventory['apples'] = 5; // Update existing value inventory.update('apples', (value) => value + 3); // Add new value if absent inventory.putIfAbsent('oranges', () => 10); print(inventory); }
The update method modifies existing entries, while putIfAbsent only adds if the key doesn't exist. Both methods help handle common update patterns safely.
$ dart main.dart {oranges: 10, apples: 8}
Iterating Over HashMap
We can iterate through HashMap entries using various methods.
import 'dart:collection'; void main() { var colors = HashMap<String, String>(); colors['red'] = '#FF0000'; colors['green'] = '#00FF00'; colors['blue'] = '#0000FF'; // Iterate keys print('Keys:'); for (var key in colors.keys) { print(key); } // Iterate values print('\nValues:'); for (var value in colors.values) { print(value); } // Iterate entries print('\nEntries:'); colors.forEach((key, value) => print('$key: $value')); }
This demonstrates three ways to iterate through a HashMap. The order is undefined since HashMap doesn't guarantee insertion order.
$ dart main.dart Keys: red green blue Values: #FF0000 #00FF00 #0000FF Entries: red: #FF0000 green: #00FF00 blue: #0000FF
Removing Elements
HashMap provides methods to remove entries by key or clear the entire map.
import 'dart:collection'; void main() { var users = HashMap<int, String>(); users[1] = 'Alice'; users[2] = 'Bob'; users[3] = 'Charlie'; users[4] = 'David'; print('Original: $users'); // Remove by key users.remove(2); print('After remove: $users'); // Remove where users.removeWhere((key, value) => key.isEven); print('After removeWhere: $users'); // Clear all users.clear(); print('After clear: $users'); }
We demonstrate three removal methods. removeWhere is powerful for bulk removal based on conditions.
$ dart main.dart Original: {1: Alice, 2: Bob, 3: Charlie, 4: David} After remove: {1: Alice, 3: Charlie, 4: David} After removeWhere: {1: Alice, 3: Charlie} After clear: {}
HashMap with Custom Objects
When using custom objects as keys, we must implement hashCode and == properly.
import 'dart:collection'; class Person { final String name; final int age; Person(this.name, this.age); @override bool operator ==(Object other) => identical(this, other) || other is Person && name == other.name && age == other.age; @override int get hashCode => name.hashCode ^ age.hashCode; } void main() { var people = HashMap<Person, String>(); var p1 = Person('Alice', 30); var p2 = Person('Bob', 25); var p3 = Person('Alice', 30); // Same as p1 people[p1] = 'Engineer'; people[p2] = 'Doctor'; people[p3] = 'Manager'; print(people); print('p1 and p3 same key: ${people[p1] == people[p3]}'); }
The Person class implements == and hashCode to ensure logical equality. p1 and p3 are considered the same key despite being different object instances.
$ dart main.dart {Person(name: Bob, age: 25): Doctor, Person(name: Alice, age: 30): Manager} p1 and p3 same key: true
Best Practices
- Key Immutability: Use immutable objects as keys for stability.
- Proper Hashing: Always override hashCode when overriding ==.
- Null Safety: Consider non-nullable types for clarity.
- Performance: Prefer containsKey over containsValue for O(1) checks.
Source
This tutorial covered Dart's HashMap with practical examples demonstrating its key features and usage patterns.
Author
List all Dart tutorials.