Map in this context is a data structure consisting of key-value pairs. You can retrieve a value by providing its key. There are three Map implementations in Dart: HashMap
, LinkedHashMap
, and SplayTreeMap
. They are different in terms of how the data is stored. However, the usage (constructors, methods and properties) are very similar. In this tutorial, I'm going to tell you the difference between those Map
implementations, the basic usages as well as list of available constructors, methods and properties.
Map
Map
is a collection of key/value pairs. In Dart, an entry of a Map
is called MapEntry
, which is a key/value pair. Retrieving a value can be done by using key name. Each entries in a Map
can be iterated. The iteration order depends on the implementation HashMap
, LinkedHashMap
or SplayTreeMap
. If you create an instance using Map
constructor, it will create a LinkedHashMap
by default.
HashMap
A HashMap
doesn't guarantee insertion order. If you insert an entry with key A and then another entry with key B, when you iterate through the map, there's a possibility that you'll get entry B first.
LinkedHashMap
Data stored in a LinkedHashMap
is sorted according to insertion order. If you insert an entry with key A and then another entry with key B, when you iterate through the map, you'll always get entry A first before entry B.
SplayTreeMap
A SplayTreeMap
is a self-balancing binary tree that allows recently accessed elements to be accessed quicker. Basic operations like insertion, look-up and removal can be done in O(log(n))
. It performs tree rotations by bringing frequently accessed elements close to the root of the tree. Therefore, if some entries need to be accessed more often than the others, using SplayTreeMap
is a good choice. However, if the data access frequency is almost the same on all entries, using SplayTreeMap is useless.
Initialization
import 'dart:collection';
main() {
HashMap map1 = new HashMap<int, String>();
LinkedHashMap map2 = new LinkedHashMap<int, String>();
SplayTreeMap map3 = new SplayTreeMap<int, String>();
}
Add/Update Value
The simplest way to add or update the value of a key is by using square brackets. It will create a new MapEntry
if no entry with the key found or update the value if there is an entry with the key.
map1[1] = 'A';
To add a MapEntry
only if an entry with the key doesn't exist in the map, use putIfAbsent
method.
map1.putIfAbsent(1, () => 'A');
To update a value if the key is already exist, use update
method.
hashMap.update(1, (e) => 'A');
hashMap.update(1, (e) => '${e}A');
The first argument is the key, while the second argument is update function. The e
parameter in the second argument function is the old value. So you can update the value based on old value, like incrementing the value if it is an integer or concatenating the old value to produce a new string like the second line of the above example. If you don't want to use the old value, just ignore it (without removing from the function argument) like the first line of the above example.
The above code only works if the key is exist. Otherwise, you'll get error. To handle the case where the key is not exist, add the optional ifAbsent
in the third argument, as exemplified below.
hashMap.update(1, (e) => '${e}A', ifAbsent: () => 'A');
Get Value by Key
To get a value if you know the key, access it by using square brackets.
map1[1]
The code above is for getting the value of entry with key 1
. If no entry with that key is found, it will return null
.
Get Map Size
To get the number of entires of a map, use length
property.
map1.length
Check Key Existance
To check whether the map contains a certain key, use containsKey
method.
map1.containsKey(1)
Check Value Existance
Not only key, you can also check whether the map contains a certain value. To do so, use containsValue
method.
map1.containsValue('A')
Remove a Key
To remove a key from a map, you can use remove
method.
map1.remove(2);
Remove by Criteria
In case you want to remove entries from map with custom logic based on key and/or value, you can use removeWhere
method. The code below is for removing entries whose key mod 2 equals 0 or whose value is C.
hashMap.removeWhere((key, value) => key % 2 == 0 || value == 'C');
Clear All Entries
To clear all entries of a map, use clear
method.
map1.clear();
Iterate Through a Map
forEach
method can be used for looping through each entry in a map.
map1.forEach((key, value) {
print('key: $key, value: $value');
});
Map a Map
With map
method, you can map not only the value of each entries, but also the key. For every entry, you need to return a new MapEntry
.
var mappedHashmap = map1.map((key, value) {
return new MapEntry(key, '$value mapped');
});
print('mappedHashmap: $mappedHashmap');
Usage Examples
Below is the usage exaples of Map
.
import 'dart:collection';
main() {
HashMap map1 = new HashMap<int, String>();
LinkedHashMap map2 = new LinkedHashMap<int, String>();
SplayTreeMap map3 = new SplayTreeMap<int, String>();
map1[1] = 'A';
print('map1: $map1');
// Print result:
// map1: {1: A}
// This should be ignored because entry with key 1 is already exist.
map1.putIfAbsent(1, () => 'A2');
// This will add entry with key 2 and value B
map1.putIfAbsent(2, () => 'B');
print('map1: $map1');
// Print result: xxx
// map1: {1: A, 2: B}
print('map1.length: ${map1.length}');
// Print result:
// map1.length: 2
// This will update the value of entry with key 1 by appending 'A' character in the end
map1.update(1, (e) => '${e}A', ifAbsent: () => 'A');
// This will create a new entry with key 3 and value C
map1.update(3, (e) => '${e}C', ifAbsent: () => 'C');
print('map1: $map1');
// Print result:
// map1: {1: AA, 2: B, 3: C}
// Retrieve the value of entry with key 1
print('Value of 1: ${map1[1]}');
// Print result:
// Value of 1: AA
// This will remove entry with key 2
map1.remove(2);
print('map1: $map1');
// Print result:
// map1: {1: AA, 3: C}
// This will remove entry whose key mods 2 equals 0 or whose value equals C
map1.removeWhere((key, value) => key % 2 == 0 || value == 'C');
print('map1: $map1');
// Print result:
// map1: {1: AA}
// Just adding other values
map1[4] = 'D';
map1[5] = 'E';
// Iterate through map entries
map1.forEach((key, value) {
print('key: $key, value: $value');
});
// Print result:
// key: 1, value: AA
// key: 4, value: D
// key: 5, value: E
var mappedHashMap = map1.map((key, value) {
return new MapEntry(key, '$value mapped');
});
print('mappedHashMap: $mappedHashMap');
// Print result:
// mappedHashMap: {1: AA mapped, 4: D mapped, 5: E mapped}
map1.clear();
print('map1: $map1');
// Print result:
// map1: {}
}
Below are the list of supported constructors, methods and properties of Map
in Dart.
Constructors
Though the constructor list is for Map
- HashMap
and LinkedHashMap
have similar constructors. Just replace the Map
with HashMap
or LinkedHashMap
.
Name | Parameters | Description |
---|---|---|
Map |
( {bool equals(K key1, K key2), int hashCode(K key), bool isValidKey(potentialKey)}) |
Creates a If if |
Map.identity |
( {bool equals(K key1, K key2), int hashCode(K key), bool isValidKey(potentialKey)}) |
Creates an identity-based map. Effectively a shorthand for: new HashMap<K, V>(equals: identical, hashCode: identityHashCode) |
Map.from |
(Map other) |
Creates a Map that contains all key/value pairs of other . |
Map.of |
(Map<K, V> other) |
Creates a Map that contains all key/value pairs of other . |
Map.fromIterable |
( {bool equals(K key1, K key2), int hashCode(K key), bool isValidKey(potentialKey)}) |
Creates a Map where the keys and values are computed from the iterable . |
Map.fromIterables |
(Iterable keys, Iterable values) |
Creates a Map associating the given keys to values . |
Map.fromEntries |
(Iterable<MapEntry<K, V>> entries) |
Creates a Map containing the entries of entries . |
SplayTreeMap
SplayTreeMap
has different constructors. It doesn't support identity
and fromEntries
, whereas the other constructors are available for it but with different parameters.
Name | Parameters | Description |
---|---|---|
SplayTreeMap |
([int compare(K key1, K key2), bool isValidKey(potentialKey)]) |
Creates a |
SplayTreeMap.from |
(Map other, [int compare(K key1, K key2), bool isValidKey(potentialKey)]) |
Creates a SplayTreeMap that contains all key/value pairs of other . |
SplayTreeMap.of |
(Map<K, V> other, [int compare(K key1, K key2), bool isValidKey(potentialKey)]) |
Creates a SplayTreeMap that contains all key/value pairs of other . |
SplayTreeMap.fromIterable |
(Iterable iterable, {K key(element), V value(element), int compare(K key1, K key2), bool isValidKey(potentialKey)}) |
Creates a SplayTreeMap where the keys and values are computed from the iterable . |
SplayTreeMap.fromIterables |
(Iterable keys, Iterable values, [int compare(K key1, K key2), bool isValidKey(potentialKey)]) { SplayTreeMap<K, V> map = new SplayTreeMap<K, V>(compare, isValidKey); MapBase._fillMapWithIterables(map, keys, values) |
Creates a SplayTreeMap associating the given keys to values . |
Methods
Name | Parameters | Description |
---|---|---|
Map<K2, V2> map<K2, V2> |
(MapEntry<K2, V2> f(K key, V value)); |
Returns a new map where all entries of this map are transformed by the given f function. |
void addEntries |
(Iterable<MapEntry<K, V>> newEntries); |
Adds all key/value pairs of newEntries to this map. |
Map<K2, V2> map<K2, V2> |
(MapEntry<K2, V2> f(K key, V value)); |
Returns a new map where all entries of this map are transformed by the given f function. |
V update |
(K key, V update(V value), {V ifAbsent()}); |
Updates the value for the provided key . Returns the new value of the key. |
void updateAll |
(V update(K key, V value)); |
Updates all values. |
void removeWhere |
(bool predicate(K key, V value)); |
Removes all entries of this map that satisfy the given predicate . |
V putIfAbsent |
(K key, V ifAbsent()); |
Look up the value of key , or add a new value if it isn't there. |
void addAll |
(Map<K, V> other); |
Adds all key/value pairs of other to this map. |
V remove |
(Object key); |
Removes key and its associated value, if present, from the map. |
void clear |
(); |
Removes all pairs from the map. |
void forEach |
(void f(K key, V value)); |
Applies f to each key/value pair of the map. |
Properties
Property | Type | Description |
---|---|---|
keys |
Iterable |
Gets the list of keys |
values |
Iterable |
Gets the list of values |
length |
Iterable |
The number of key/value pairs in the map. |
isEmpty |
bool |
Returns true if there is no key/value pair in the map. |
isNotEmpty |
bool |
Returns true if there is at least one key/value pair in the map. |
entries |
Iterable<MapEntry<K, V>> |
The map entries of this . |
hashCode |
int |
The hash code for this object. |