Hash Tables, better known as Hash Maps, are just collections of key-value pairs. In other words, they are pieces of data (values) mapped to unique identifiers called properties (keys).
Hash Maps were designed to give us a way of, given a key, associating a value with it for very quick lookups.
In Kotlin, a Hash Map is a MutableMap created with mutableMapOf() or hashMapOf(). Both are backed by a HashMap (mutableMapOf() returns a LinkedHashMap, a hash map that also remembers insertion order).
Creation:
You create an empty Hash Map by declaring a MutableMap<keyType, valueType> and initializing it with mutableMapOf(), where the keyType and valueType are the data types of the keys and values.
Let's declare a Hash Map that maps text values represing digits to their numerical value (e.g. "two" => 2). We wil map strings to integers, so the two types are String and Int. We will name the map digitValue
val digitValue: MutableMap<String, Int> = mutableMapOf()
Creating an empty dictionary takes O(1) time.
Initialization:
You can also add some key-value pairs in your dictionary at creation:
val digitValue: MutableMap<String, Int> = mutableMapOf(
"zero" to 0,
"one" to 1
)
Accessing values:
A value is retrieved from a map using square brackets, map[key] (which calls get()):
val digitValue: MutableMap<String, Int> = mutableMapOf(
"zero" to 0,
"one" to 1
)
// Accesing values:
digitValue["zero"] // returns 0
digitValue["one"] // returns 1
digitValue["three"] // returns null since 'three' does not exist
digitValue.getOrDefault("three", 0) // returns 0 as the default value
As you can see, if you refer to a key that is not in the map, Kotlin gives you null and raises no exception. We can use getOrDefault to specify a default value in case it does not exist
Accessing a value from a map takes O(1) time.
Adding an entry:
We can add a key / value pair by assigning to map[key] (which calls put()) as follows:
val digitValue: MutableMap<String, Int> = mutableMapOf(
"zero" to 0,
"one" to 1
)
// Adding new entries:
digitValue["three"] = 3
//The new Hash Map:
// {
// "zero": 0,
// "one": 1,
// "three": 3
//}
Adding a new entry to a map takes O(1) time.
Updating an entry:
We can update an existing entry by assigning to map[key] as follows:
val digitValue: MutableMap<String, Int> = mutableMapOf(
"zero" to 0,
"one" to 1
)
// updating entries:
digitValue["zero"] = 5
//the new hash map:
// {
// "zero": 5,
// "one": 1
//}
Updating an entry from a map takes O(1) time.
Deleting entries:
The remove() method allows you to remove a key from a map:
val digitValue: MutableMap<String, Int> = mutableMapOf(
"zero" to 0,
"one" to 1
)
// removing entries:
digitValue.remove("zero")
//the new hash map:
// {
// "one": 1
//}
If you try to delete a key that is not in the map, it won't do anything.
Deleting an entry from a map takes O(1) time.
Checking if a key exists:
You can check if a key exists in a map using the containsKey() method:
val digitValue: MutableMap<String, Int> = mutableMapOf(
"zero" to 0,
"one" to 1
)
digitValue.containsKey("zero") // returns true since the key exists
digitValue.containsKey("three") // returns false since the key does not exist
Checking if a key exists in the map is O(1) time.
Iterating over the map keys:
If we want to iterate over keys of the map, we can use the for loop along with the in keyword and the keys property as follows:
val digitValue: MutableMap<String, Int> = mutableMapOf(
"zero" to 0,
"one" to 1
)
for (key in digitValue.keys) {
println("$key is ${digitValue[key]}")
}
// This will print:
// zero is 0
// one is 1
Notice the order: mutableMapOf() keeps the keys in the order they were added. A plain HashMap (for example from hashMapOf()) makes no promise about the order, so don't rely on it.
Iterating over a dictionary takes O(n) time.
Assignment
Follow the Coding Tutorial and let's play with some dictionaries.
Hint
Look at the examples above if you get stuck.
Free plan: 30 tutor messages. PRO is unlimited.
