IndexMap<K, V> class abstract final Collections

A hash map where element iteration order is independent of their hash codes.

Iteration Order

The keys, K, have a consistent order that is determined by the sequence of operator[]= and remove calls (or similar operations):

final map = IndexMap<int, String>();
map[1] = 'a';
map[2] = 'b';
map[3] = 'c';
map.remove(2);
print(map); // {1: 'a', 3: 'c'}

Unlike LinkedHashMap, remove calls (and similar operations) shift the iteration order; a removed element is swapped with the last element in the map, and then removed:

final map = IndexMap<int, String>();
map[1] = 'a';
map[2] = 'b';
map[3] = 'c';
map.remove(1);
print(map); // {3: 'c', 2: 'b'}

Index Access

Like IndexSet, IndexMap provides an additional set of operators.

entryAt returns a specialized key-value pair type, IndexedMapEntry. A logical extension to MapEntry, IndexedMapEntry not only contains the key and value, but also the index of the element in the iteration sequence:

final map = IndexMap<String, bool>();
map['a'] = true;
map['b'] = false;

final entry = map.getEntryAt(1);
print(entry.key); // 'b'
print(entry.value); // false
print(entry.index); // 1

However, unlike even Map, IndexMap can return an IndexedMapEntry even if the key is not yet present in the map, giving a powerful and performant way to insert elements at a specific index, using entryOf and IndexedMapEntry.setOrUpdate.

final map = IndexMap<String, bool>();
map['a'] = true;

final a = map.tryGet('a');
print(a.isPresent); // true
print(a.key); // 'a'
print(a.value); // true
a.value = false;
a.setOrUpdate(false);
print(map); // {a: false}

final b = map.tryGet('b');
print(b.isAbsent); // false
print(b.key); // 'b'
print(b.value); // n

b.setOrUpdate(false);
print(map); // {a: false, b: false}

Performance

If you want the properties of IndexMap, or its strongest performance characteristics fit your workload, it might be the fastest pure Dart Map implementation available; for example package:sector uses it internally for its graph search algorithms.

IndexMap derives some performance facts from how it is constructed:

  1. Iteration is as fast as a List (~2-3x faster than dart:collection).
  2. Removals are nearly as fast as HashMap (~300-400x faster).
  3. Creation is ~2x slower than HashMap, 5x faster than LinkedHashMap.

Tip

Profile your workload to be sure.

Implemented types

Constructors

IndexMap({bool equals(K e1, K e2)?, int hashCode(K e)?, bool isValidKey(Object? potentialKey)?})
Creates an insertion-ordered indexing based Map.
factory
IndexMap.from(Map<K, V> other)
Creates an IndexMap from other.
factory
IndexMap.fromEntries(Iterable<MapEntry<K, V>> entries)
Creates an IndexMap from entries.
factory
IndexMap.identity()
Creates an IndexMap that uses identical and identityHashCode.
factory

Properties

entries → Iterable<MapEntry<K, V>>
The map entries of this Map.
no setterinherited
hashCode → int
The hash code for this object.
no setterinherited
isEmpty → bool
Whether there is no key/value pair in the map.
no setterinherited
isNotEmpty → bool
Whether there is at least one key/value pair in the map.
no setterinherited
keys → Iterable<K>
The keys of this Map.
no setterinherited
length → int
The number of key/value pairs in the map.
no setterinherited
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
values → Iterable<V>
The values of this Map.
no setterinherited

Methods

addAll(Map<K, V> other) → void
Adds all key/value pairs of other to this map.
inherited
addEntries(Iterable<MapEntry<K, V>> newEntries) → void
Adds all key/value pairs of newEntries to this map.
inherited
cast<RK, RV>() → Map<RK, RV>
Provides a view of this map as having RK keys and RV instances, if necessary.
inherited
clear() → void
Removes all entries from the map.
inherited
containsKey(Object? key) → bool
Whether this map contains the given key.
inherited
containsValue(Object? value) → bool
Whether this map contains the given value.
inherited
entryAt(int index) → PresentMapEntry<K, V>
Returns the map entry at the given index.
entryOf(K key) → IndexedMapEntry<K, V>
Returns the map entry for the given key.
forEach(void action(K key, V value)) → void
Applies action to each key/value pair of the map.
inherited
map<K2, V2>(MapEntry<K2, V2> convert(K key, V value)) → Map<K2, V2>
Returns a new map where all entries of this map are transformed by the given convert function.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
putIfAbsent(K key, V ifAbsent()) → V
Look up the value of key, or add a new entry if it isn't there.
inherited
remove(Object? key) → V?
Removes key and its associated value, if present, from the map.
inherited
removeWhere(bool test(K key, V value)) → void
Removes all entries of this map that satisfy the given test.
inherited
toString() → String
A string representation of this object.
inherited
update(K key, V update(V value), {V ifAbsent()?}) → V
Updates the value for the provided key.
inherited
updateAll(V update(K key, V value)) → void
Updates all values.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited
operator [](Object? key) → V?
The value for the given key, or null if key is not in the map.
inherited
operator []=(K key, V value) → void
Associates the key with the given value.
inherited