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.