- Introduction to Dart Map, HashMap, LinkedHashMap, SplayTreeMap
- How to create, initialize, add, get value, update, remove entriess in a Map
- Ways to iterate, search, filter, transform a Map in Dart/Flutter
- Way to sort a Map in Dart/Flutter A Dart Map is a collection of key-value pairs. It maps each key to exactly one value. We can iterate over a Map.
- HashMap is unordered. The key-value pair coming later could be ordered first.
- LinkedHashMap has predictable iteration order by the insertion order. The key-value pair coming later will be ordered later.
- SplayTreeMap iterates the keys in sorted order. It is a self-balancing binary tree, frequently accessed elements will be moved more closely to the root of the tree.
creating an instance using Map constructor (Map(), Map.from(), Map.of()) will return a LinkedHashMap.
Create a new Map in Dart/Flutter
Using new keyword, we can create a new Map.
Don’t forget to import dart:collection library before using these syntax containing HashMap, LinkedHashMap, SplayTreeMap, also other code in the rest of this tutorial.
import 'dart:collection';
main() {
HashMap hashMap = new HashMap<int, String>();
LinkedHashMap linkedHashMap = new LinkedHashMap<int, String>();
SplayTreeMap treeMap = new SplayTreeMap<int, String>();
}
With recent Dart version, we don’t need to use new keyword anymore.
For example,HashMap map = HashMap<int, String>()
is accepted.
We can create a new LinkedHashMap using Map constructor like this.
Map map = Map<int, String>();
if (map is LinkedHashMap) {
print("This is a LinkedHashMap.");
}
// Result: This is a LinkedHashMap.
In the code above, we specify the type of key-value pairs: .
You can also declare a Map, LinkedHashMap, SplayTreeMap without setting the type for their keys and values. What does it mean? It will not constrain us to add a pair into the Map.
These Maps now accept other types: <String, String>, <String, int>…
Map map = Map();
HashMap map1 = HashMap();
LinkedHashMap map2 = LinkedHashMap();
SplayTreeMap map3 = SplayTreeMap();
Initialize a Map with values in Dart/Flutter
The examples show you how to:
initialize Map in simple way using {} (curly braces).
- create a Map with all key/value pairs of other Map using from(), of() constructor.
- create a new Map from the given keys and values using fromIterables().
- create Map in which keys and values are computed using fromIterable()
- create a ‘const’ Map using unmodifiable() constructor.
Map<String, int> map1 = {'zero': 0, 'one': 1, 'two': 2};
print(map1);
// not specify key-value type
Map map2 = {'zero': 0, 'I': 'one', 10: 'X'};
print(map2);
var map3 = {'zero': 0, 'I': 'one', 10: 'X'};
print(map3);
Remember that when we use Map or var, the type will always be
LinkedHashMap.
`Output:
{zero: 0, one: 1, two: 2}
{zero: 0, I: one, 10: X}
{zero: 0, I: one, 10: X}`
Map<String, int> map1 = {'zero': 0, 'one': 1, 'two': 2};
Map map2 = Map.from(map1);
print(map2);
Map map3 = Map.of(map1);
print(map3);
Output:
{zero: 0, one: 1, two: 2}
{zero: 0, one: 1, two: 2}
List<String> letters = ['I', 'V', 'X'];
List<int> numbers = [1, 5, 10];
Map<String, int> map = Map.fromIterables(letters, numbers);
print(map);
`Output:
{I: 1, V: 5, X: 10}`
List<int> numbers = [1, 2, 3];
Map<String, int> map = Map.fromIterable(
numbers,
key: (k) => 'double ' + k.toString(),
value: (v) => v * 2);
`print(map);
Output:
{double 1: 2, double 2: 4, double 3: 6}`
Map map = Map.unmodifiable({1: 'one', 2: 'two'});
print(map);
// {1: one, 2: two}
map[3] = 'three';
If you try to modify/add object to the unmodifiable Map, it will throw an error.
Unhandled exception:
Unsupported operation: Cannot modify unmodifiable map
Difference between Map.from() and Map.of
Look at the example below, we try to create two Map with wrong type:
Map<int, String> map = {1: 'one', 2: 'two'};
Map<String, String> map1 = Map.from(map); // runtime error
Map<String, String> map2 = Map.of(map); // compilation error
You can see that:
– Map.from(map) doesn’t cause any compilation error. When we run the statement, the error occurs:
Unhandled exception:
type 'int' is not a subtype of type 'String'
This is because of its prototype:
Map<K, V> Map.from(Map<dynamic, dynamic> other)
When we pass a Map<int, String> map to the function, it converts the key-value pair type into Map<dynamic, dynamic>.
– Map.of(map) doesn’t do that thing, it keep the key-value pair type, so the compiler realizes the error before running the program.
Map<K, V> Map.of(Map<K, V> other)
Dart/Flutter Map collection if and collection for
With the collection if and collection for, we can dynamically create maps using conditionals (if) and repetition (for).
var mobile = true;
var myMap = {1: 'kotlin', 2: 'dart', if (mobile) 3: 'flutter'};
// {1: kotlin, 2: dart, 3: flutter}
var squareMap = {
for (var i = 1; i <= 5; i++) i: i * i
};
// {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
var tringList = ['kotlin', 'dart', 'flutter', 'react'];
var i = 0;
var data = {for (var s in tringList) if (s.length > 5) i++: s};
// {0: kotlin, 1: flutter}
Add item to a Map in Dart/Flutter
There are 2 way to add an item (key-value pair) to a Map:
using square brackets []
calling putIfAbsent() method
Map map = {1: 'one', 2: 'two'};
map[3] = 'three';
print(map);
var threeValue = map.putIfAbsent(3, () => 'THREE');
print(map);
print(threeValue); // the value associated to key, if there is one
map.putIfAbsent(4, () => 'four');
print(map);
`Output:
{1: one, 2: two, 3: three}
{1: one, 2: two, 3: three}
three
{1: one, 2: two, 3: three, 4: four}`
You can add all key/value pairs of another Map to current Map using addAll() method.
Map map = {1: 'one', 2: 'two'};
map.addAll({3: 'three', 4: 'four', 5: 'five'});
print(map);
Output:
{1: one, 2: two, 3: three, 4: four, 5: five}
Map update value by key in Dart/Flutter
The examples show you how to update a Map value using:
square brackets []
update() method
update() method with ifAbsent to add a new object/entry if the input key is absent
Map map = {1: 'one', 2: 'two'};
map[1] = 'ONE';
print(map);
map.update(2, (v) {
print('old value before update: ' + v);
return 'TWO';
});
print(map);
map.update(3, (v) => 'THREE', ifAbsent: () => 'addedThree');
print(map);
Output:
{1: ONE, 2: two}
old value before update: two
{1: ONE, 2: TWO}
{1: ONE, 2: TWO, 3: addedThree}
Access items from Map in Dart/Flutter
The examples show you way to:
- find the number of key/value pairs using .length getter.
- check if a Map is empty or not using .isEmpty or .isNotEmpty.
- get all keys or values with keys & values property.
- get value of specified key in a Map or operator [].
Map map = {1: 'one', 2: 'two'};
print(map.length); // 2
print(map.isEmpty); // false
print(map.isNotEmpty); // true
print(map.keys); // (1, 2)
print(map.values); // (one, two)
print(map[2]); // two
print(map[3]); // null
Dart/Flutter check existence of key/value in Map
We can check existence of:
- a key using containsKey() method.
- a value using containsValue() method.
Map map = {1: 'one', 2: 'two'};
print(map.containsKey(1)); // true
print(map.containsKey(3)); // false
print(map.containsValue('two')); // true
print(map.containsKey('three')); // false
Remove objects from Map in Dart/Flutter
The examples show you how to:
- remove key-value pair by key using remove() method.
- remove all entries with condition using removeWhere() method.
- remove all entries from a Map using clear() method.
Map map = {1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five'};
map.remove(2);
print(map);
map.removeWhere((k, v) => v.startsWith('f'));
print(map);
map.clear();
print(map);
Output:
{1: one, 3: three, 4: four, 5: five}
{1: one, 3: three}
{}
Combine/merge multiple Maps in Dart/Flutter
The examples show how to combine Maps using:
addAll() method
from() and addAll() method
spread operator ... or null-aware spread operator ...? (from Dart 2.3)
Map map1 = {1: 'one', 2: 'two'};
Map map2 = {3: 'three'};
Map map3 = {4: 'four', 5: 'five'};
// addAll() method
var combinedMap1 = {}..addAll(map1)..addAll(map2)..addAll(map3);
print(combinedMap1);
// from() and addAll() method
var combinedMap2 = Map.from(map1)..addAll(map2)..addAll(map3);
print(combinedMap2);
// spread operator
var combinedMap3 = {...map1, ...map2, ...map3};
print(combinedMap3);
Output:
{1: one, 2: two, 3: three, 4: four, 5: five}
What if there is one of 3 Maps is null:
Map map1 = {1: 'one', 2: 'two'};
Map map2 = null;
Map map3 = {4: 'four', 5: 'five'};
If we combine these Maps using the methods above, the program will throw Exception:
NoSuchMethodError: The getter 'keys' was called on null.
To deal with it, we use null-aware spread operator ...?. The operator check null Map automatically with only one more ? symbol:
var combinedMap = {...?map1, ...?map2, ...?map3};
print(combinedMap);
Output:
{1: one, 2: two, 4: four, 5: five}
Iterate over Map in Dart/Flutter
The examples show you how to iterate over a Dart Map using:
forEach() method.
entries property and forEach() method.
Map map = {1: 'one', 2: 'two', 3: 'three'};
map.forEach((k, v) {
print('{ key: $k, value: $v }');
});
map.entries.forEach((e) {
print('{ key: ${e.key}, value: ${e.value} }');
});
Output:
{ key: 1, value: one }
{ key: 2, value: two }
{ key: 3, value: three }
We can iterate over keys or values using Map property and
forEach() method.
map.keys.forEach((k) => print(k));
map.values.forEach((v) => print(v));
`Output:
1
2
3
one
two
three`
Dart/Flutter Map get key by value
Dart Map supports getting value by key, how about the opposite?
We can get key by a specified value using keys property and List firstWhere() method.
Map map = {1: 'one', 2: 'two', 3: 'three'};
var key = map.keys.firstWhere((k) => map[k] == 'two', orElse: () => null);
print(key);
// 2
Sort a Map in Dart/Flutter
The example shows you how to sort a Map by values using Map fromEntries() method and List sort() method.
Map map = {1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five'};
var sortedMap = Map.fromEntries(
map.entries.toList()
..sort((e1, e2) => e1.value.compareTo(e2.value)));
print(sortedMap);
Output:
{5: five, 4: four, 1: one, 3: three, 2: two}
For more details about sorting with List, please visit:
Sorting a List in Dart/Flutter
Map.map() method to transform a Map in Dart/Flutter
We can use map() method to get a new Map with all entries are transformed.
For example, the code below change keys and uppercase values of all entries.
Map map = {1: 'one', 2: 'two', 3: 'three'};
var transformedMap = map.map((k, v) {
return MapEntry('($k)', v.toUpperCase());
});
print(transformedMap);
Output:
{(1): ONE, (2): TWO, (3): THREE}
Top comments (0)