Dart/Flutter Map, HashMap Tutorial with Examples

In this tutorial, we’ll show you many methods and functions to work with a Map in Dart (also in Flutter). You will know:

  • 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

Related Posts:
Dart/Flutter – Convert Object to JSON string
Dart/Flutter – Convert/Parse JSON string, array into Object, List
Dart/Flutter – Convert Map to List & List to Map

Dart/Flutter Constructors tutorial with examples
Dart/Flutter String Methods & Operators tutorial with examples
Dart/Flutter Future Tutorial with Examples
Dart/Flutter List Tutorial with Examples


Key points to note about Dart Map

A Dart Map is a collection of key-value pairs. It maps each key to exactly one value. We can iterate over a Map.

There are three types of map, depending in the order of iteration:

  • 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.

By default, creating an instance using Map constructor (Map(), Map.from(), Map.of()) will return a LinkedHashMap.

So in the next sections, wherever we use Map, you can think about LinkedHashMap, and you can also replace Map with 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: <int, String>.
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 <int, String> 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:

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:

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:

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}

Conclusion

In this Dart/Flutter tutorial, we’ve learned some important points of Dart Map, HashMap, LinkedHashMap, how to create, initialize a Map, how to add, update and remove items from a Map, how to combine Maps, how to iterate over a Map, sort, transform a Map.

Happy learning! See you again!

Further Reading

Dart/Flutter – Convert Object to JSON string
Dart/Flutter – Convert/Parse JSON string, array into Object, List
Dart/Flutter – Convert Map to List & List to Map

Dart/Flutter Constructors tutorial with examples
Dart/Flutter String Methods & Operators tutorial with examples
Dart/Flutter Future Tutorial with Examples
Dart/Flutter List Tutorial with Examples

31 thoughts to “Dart/Flutter Map, HashMap Tutorial with Examples”

  1. I truly appreciate this post. I’ve been looking everywhere for full Dart Map tutorial! You have made my day! Thank you!

  2. Thanks for this comprehensive tutorial about Kotlin Map. Please make more Dart data structure tutorials like this.

    1. Hi, you can add Lists to a Map like this:

      Map<String, List<int>> myMapList = Map();
      
      myMapList['listA'] = [1, 2, 3];
      myMapList['listB'] = [4, 5, 6];
      
      print(myMapList);
      // {listA: [1, 2, 3], listB: [4, 5, 6]}
      

      Or Map to a Map as following code:

      Map<String, Map<String, int>> myMapMap = Map();
      
      myMapMap['mapA'] = {'A1': 1, 'A2': 2};
      myMapMap['mapB'] = {'B1': 3, 'B2': 4};
      
      print(myMapMap);
      // {mapA: {A1: 1, A2: 2}, mapB: {B1: 3, B2: 4}}
      
  3. Thank you so much for the detailed post. I really appreciate it. BTW, I’m working with a List<Map<String, List>> elementList = [], which is:

    list: [
          {
            'Morning': ['one', 'two']
          },
       
          {
            'Evening': ['five', 'six']
          },
        ], 
    

    I want to add ‘three’ to the list of map in which map.containsKey('Morning'). How do I iterate it?

    1. Hi, you can use the following code:

      List> elementList = [];
      elementList.add({
        "Morning": ["one", "two"]
      });
      elementList.add({
        "Evening": ["five", "six"]
      });
      
      print(elementList);
      // [{Morning: [one, two]}, {Evening: [five, six]}]
      
      int index = elementList.indexWhere((map) => map.containsKey("Morning"));
      
      elementList[index]["Morning"].add("three");
      print(elementList);
      // [{Morning: [one, two, three]}, {Evening: [five, six]}]
      
      elementList[index]["Morning"].forEach((item) => print(item));
      /*
      one
      two
      three
      */
      
  4. Thank you so much for posting this. I was really struggling with using Map.map() and every other site I’ve found completely skips any mention of it. Pretty simple once you understand the need to return a MapEntry.

    Great Job!

  5. Thank you so much for this comprehensive tutorial. I’m new to Dart, I’m learning Dart data structure and the tutorial help me alot.

  6. List A = [idA1, idA2, idA3]
    List B = [
      {idB1,idA1},
      {idB2,idA1},
      {idB3,idA2},
      {idB4,idA2},
      {idB5,idA3}
    ]
    

    How to convert to Map<int,List> map.
    Result:

    map = (
                  {
                    idA1:[idB1,idB2]
                 },
                  {
                   idA2:[idB3,idB4]
                 },
                  {
                   idA3:[idB5]
                 }
    )
    

    Thanks!

  7. You should take part in a contest for one of the finest sites on the internet.
    I most certainly will recommend this web site!

  8. I just want to say Thank You because it is really good.

    I want to ask? usually we crease a model class such as class Cart { final String itemno; final double price; final int quantity; Cart( @required this.itemno, @required this.price, @required this.quantity); }

    now I want to create a model class for order so class Order { final String orderno; String Date; ? how to add the above cart map Order( @required this orderno, @required this.date, @required this.cart); }

  9. This was a great, concise and informative post. It really helped me learn a lot about maps and there usage quickly. It’s really appreciated. Thanks!

  10. Wow! This can be one particular of the most beneficial blogs We have ever arrive across on Dart/Flutter basics. Actually Great! I’m also an expert in Dart so I can understand your hard work.

Leave a Reply

Your email address will not be published. Required fields are marked *