Understanding Maps 🗺 in the Kotlin.
Curious how Kotlin resolve the Java platform’s map?
This Post is given `Silver award` in Reddit at r/android_devs,thanks community for supporting my blogs and it really motivating me! 🙇♂️
AndroidBites | Java ☕️ Maps 🗺 on the Kotlin. from android_devs
Originally Posted At :

Most of the Kotlin developers are migrated from the Java environment, they are pretty well versed with uses-cases and application of Collection Framework in the Java platform, but applying the same knowledge in a Kotlin codebase isn’t guaranteed to work always. You could end up with a spaghetti codebase base having a long trailing function and making hacks to achieve a functionality that could easily be solved using Kotlin’s standard functions easily. Kotlin stdlib which offers generic interfaces, classes, and functions for creating, populating, and managing Collections of any type.
In Today’s article, we will try to understand how Kotlin catered to Java Maps in his its colors. Disclaimer This article is specific to Kotlin JVM as collection implementation varies with the platform you are targeting in Kotlin. I’m Chetan Gupta, I do tech stuff, don’t forget to checkout from other blogs as well from AndroidBites, without any delays, Let’s get started.

Map 🗺
It’s a collection of key-value pairs, mainly focus on retrieving a value against the key.
// signature
interface Map<K, out V>
// Parameters
// K - the type of key
// V - the type of map values
- Keys are unique and similar to the index of an array.
- A map can hold only one value against a key.
- The map is a read-only collection but for the sake of understanding, I will be addressing it as Immutable*.
- The modifying part is supported using Mutable maps, discussed later in the article.
Map<K, V>
is not an inheritor of the Collection Interface, but it’s the part of the Kotlin Collection type.
Entries 🚪
An entry represents a key/value pair in a map.
// signature
interface Entry<out K, out V>
// Parameters
// K - the type of key
// V - the type of map values
A map contains a Set<Entry<K,V>>
type entries to store its key/value, since its a Set, the uniqueness is enforced into the map entries.
val map = object : Map<String, Int>{
override val entries: Set<Entry<String, Int>>
get() = //stuff...
}
Even though an entry
is representing a key-value pair in a map, there is no way to directly create a map using it i.e if you can see possible ways we can create a map :
fun <K, V> mapOf(): Map<K, V>
fun <K, V> mapOf(pair: Pair<K, V>): Map<K, V>
fun <K, V> mapOf(vararg pairs: Pair<K, V>): Map<K, V>
There is no function which creates a map using the Entry, if you check Entry
Interface
from docs, you will see
fun <K, V> Entry<K, V>.toPair(): Pair<K, V>
Entry can be converted to Pair but not to a map directly (like a SingletonMap), even if you focus on entries in the map which are Set<Entry<K, V>>
there is no function that converts a Set<Entry<String, Int>>
into Map.
fun <K, V> Iterable<Entry<K, V>>.toMap(): Map<K, V> Or any other isn't supported
// but instead there is
fun <K, V> Iterable<Pair<K, V>>.toMap(): Map<K, V>
Since there is no direct support of entries to map, hence we can conclude that it’s used only as an internal implementation of key/value entries, but for the outside world it has to implement using Pair type.
// enteries to map example
val entries:Set<Entry<String, Int>> = setOf(entry)
val map = entries.map { entry -> entry.toPair() }.toMap()
// here, entries.map { entry -> entry.toPair() }
// is List<Pair<String,Int>> i.e Iterable<Pair<K, V>>.toMap()
Since we are creating Maps using Pair
, let’s focus on what is it?
Enjoying the Post?
a clap is much appreciated if you enjoyed. No sign up or cost associated :)
If you want to support my content do consider dropping a tip/coffee/donation💰
Pair 👥
A Pair represents a generic pair of two values. It is a separate data structure, which is not a part of the Collection Framework. It can be used for any purpose.
data class Pair<out A, out B> : Serializable
It isn’t necessary that the first
and the second
the element of the Pair
holds any relation with each other, but Entry’s first element i.e key
has a relation with the second element i.e value
.
But since Entry
can’t be used to create maps directly there was no logical point in having a standard extension that converts Pair
into Map.Entry
type, thus stdlib doesn’t have Pair.toEntry()
function.
There is a discussion in the form regarding it but it goes nowhere.

Since Pair
are used to create Map
, the extension below supports that Idea.
// Pair Iterable has a extension which convert
// List<Pair<String,Int>> to Map
fun <K, V> Iterable<Pair<K, V>>.toMap(): Map<K, V>
// other implementation with d
Map
is the base Interface for AbstractMap
and MutableMap
, so all the core ADT functions such as get
, put
, contains
, containsKey
, isEmpty
, size
etc are implemented in it.
Check out the complete list of base functions from docs :

mapOf 👷♂️
If you have focused on Map signature interface Map<K, out V>
, it’s an interface, i.e it needs to have an implementing class.
In Kotlin, we have three functions for implementing maps and all of them are resolved using different implementations of Map.
// Kotlin Standard Library function
fun <K, V> mapOf(): Map<K, V>
fun <K, V> mapOf(pair: Pair<K, V>): Map<K, V>
fun <K, V> mapOf(vararg pairs: Pair<K, V>): Map<K, V>
fun <K, V> mapOf(): Map<K, V> = emptyMap()
// emptyMap is resolved by
object EmptyMap : Map<Any?, Nothing>, Serializable
// which return read-only empty map implementation
fun <K, V> mapOf(pair: Pair<K, V>): Map<K, V>
= java.util.Collections.singletonMap(pair.first, pair.second)
// In java.util.Collections,
public static Map singletonMap(K key, V value)
//a function that return an immutable map, which is serializable.
//it is mapping only the specified key to the specified value.
fun <K, V> mapOf(vararg pairs: Pair<K, V>): Map<K, V>
= if (pairs.size > 0){
pairs.toMap(LinkedHashMap(mapCapacity(pairs.size)))
}else{
emptyMap()
}
// Linked HashMap signature
class LinkedHashMap<K, V> : MutableMap<K, V>
// since MutableMap<K, V> has Map as parent class
// Casting it to map make it immutable* (read-only)
So if you are working with a map which has more than one entry, is highly likely to be resolved by using an implementation of LinkedHashMap
. We will know about it later in the article.
TLDR ☕️
Maps :
- Maps are read-only key/value pair of collection
- They use Entry to represent the internal state of key/value
- You use Pairs to create a map
- Maps implementation varies but is mostly resolved with LinkedHashMap
Enjoying the Post?
a clap is much appreciated if you enjoyed. No sign up or cost associated :)
If you want to support my content do consider dropping a tip/coffee/donation💰
Mutable Map 📝
As the name suggests, it’s a mutable implementation of a Map
. It’s a modifiable version of the map.
interface MutableMap<K, V> : Map<K, V>
Similar to Map, MutableMap has MutableEntry
that represents a key/value pair but unlike Entry it is mutable :
abstract fun setValue(newValue: V): V
Entries in the mutableMap
is now a MutableSet
:
abstract val entries: MutableSet<MutableEntry<K, V>> is a MutableSet
Since Map
was immutable*(read-only), there was no mutable function such as :
// return old value, if updating existing entry else null
abstract fun put(key: K, value: V): V?
abstract fun putAll(from: Map<out K, V>)
abstract fun clear()
// return removed value, if not existing then null
abstract fun remove(key: K): V?
open fun remove(key: K, value: V): Boolean
All the functions available in the Map are overridden using mutable type variants, You can check them out from docs :

Mutable Pair? 🤔
Since you now see everything is implemented in Mutable Maps using mutable types, means Pair which are used to construct mutable map should have a mutable implementation as well, isn’t it?
Logically your thinking is right but only if you look it in terms of Collection, Pairs are not part of collection.
The immutability and Mutability collections concept is introduced to provide a read-only protection*. This helps Kotlin Compiler to show an error at compile-time rather than runtime, for example In Java, java.util.Collections.unmodifiableList(java.util.List)
the error would be only visible to the user when he tries to update the unmodifiable list at runtime.
read-only protections, are used to safeguard values in a collection from accidental updates
So how do we update Pair values?
It’s easy, you can directly use the copy constructor, for example :
val pair = "2" to 1
val updatedPair = pair.copy(first = "1")
The last thing in your mind would be, do we need to use ListOf<Pair<K,V>>
or MutableListOf<Pair<K,V>>
to create a mutable map?
To answer this, you need to know both List
and MutableList
both are of an iterable
type so doesn’t matter, you can create a map using both.
// Pair Iterable has a extension which convert
// List<Pair<String,Int>> to Map
fun <K, V> Iterable<Pair<K, V>>.toMap(): Map<K, V>
// other implementation with d
Other part is you can’t directly convert a List
or MutableList
to MutableMap
, there is no direct extension available :
// you need to first convert to map
mutableListOf<Pair<String,Int>>(pair,updatedPair).toMap()
// then you have access to mutableMap extension
mutableListOf<Pair<String,Int>>(pair,updatedPair).toMap().toMutableMap()
//signature
fun <K, V> Map<out K, V>.toMutableMap(): MutableMap<K, V>
MutableMap is the base interface of AbstractMutableMap
, HashMaps
and LinkedHashMap
.
Enjoying the Post?
a clap is much appreciated if you enjoyed. No sign up or cost associated :)
If you want to support my content do consider dropping a tip/coffee/donation💰
mutableMapOf 👷♂️
Similar to Map signature, interface MutableMap<K, out V>
, it’s an interface, i.e it needs to have an implementing class.
In Kotlin, we have two function implementation of these and both of them is resolved using LinkedHashMap
// Kotlin Standard Library function
fun <K, V> mutableMapOf(): MutableMap<K, V>
fun <K, V> mutableMapOf(vararg pairs: Pair<K, V> ): MutableMap<K, V>
fun <K, V> mutableMapOf(): MutableMap<K, V> = LinkedHashMap()
// mutableMapOf is resolved using LinkedHashMap
// as discussed earlier Linked HashMap signature
class LinkedHashMap<K, V> : MutableMap<K, V>
fun <K, V> mutableMapOf(vararg pairs: Pair<K, V>): MutableMap<K, V>
= LinkedHashMap<K, V>(mapCapacity(pairs.size))
.apply { putAll(pairs) }
// resolved with LinkedHashMap only
TLDR ☕️
Mutable Maps :
- Mutable Maps are modifiable key/value pairs of collection therefore contain functions such as put, remove, clear etc that can modify the map.
- They use MutableEntry to represent the internal state of key/value
- Pairs don’t have mutable counter-part, Pairs are used to create the map, then that map is transformed to MutableMap.
- All of the function implementations is resolved by LinkedHashMap
HashMap 📝
In Kotlin JVM, HashMap is a type alias for Java’s HashMap
// Kotlin signature
typealias HashMap<K, V> = HashMap<K, V>
// Java signature
class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
// AbstractMap<K,V> is a skeletal implementation of the Map interface,
// Java's Map<K,V> is very close to MutableMap<K,V> than kotlin's Map<K,V>
// i.e it contains mutable opertaions internally, though use structures named
// similar to Kotlin's Map<K,V> like Map.Entry but are infact Mutable Entry
Java HashMap has three constructors
- HashMap()
- HashMap(int initialCapacity)
- HashMap(int initialCapacity,float fillRatio)
- HashMap(Map<K,V> fromMap)
HashMap in Java is a Hash table based implementation of the (Mutable) Map interface.
- Insertion Order is not preserved, insertion is based on the hashcode of keys, not the values
- Duplicate keys entry is not allowed
- Heterogeneous key/value entry is allowed
- Null keys are allowed but only once, you can store any null values
NOTE.
Even if Kotlin uses typealias
and call Java Hashmap the interpolation with Kotlin maps its return types to the MutableMap
interface of Kotlin, i.e when you call hashMap.entries
you will get MutableSet<MutableEntry>
not Java’s Set<Entry>
.
Learn more about all the APIs of HashMap from:
Enjoying the Post?
a clap is much appreciated if you enjoyed. No sign up or cost associated :)
If you want to support my content do consider dropping a tip/coffee/donation💰
hashMapOf 👷♂️
Kotlin provides two implementations to create HashMap
// Kotlin Standard Library function
fun <K, V> hashMapOf(): HashMap<K, V>
fun <K, V> hashMapOf(vararg pairs: Pair<K, V>): HashMap<K, V>
fun <K, V> hashMapOf(): HashMap<K, V> = HashMap<K, V>()
// hashmapOf directly create HashMap object default constructor
// Java HashMap default constructor create HashMap with
// * inital capacity 16 and * LoadFactor 0.75
fun <K, V> hashMapOf(vararg pairs: Pair<K, V>): HashMap<K, V>
= HashMap<K, V>(mapCapacity(pairs.size)).apply { putAll(pairs) }
// this factory function takes pair and uses HashMap's second constructor which
// start off with the object capacity as the number of pairs passed
Another way by which you can create a hashmap is by creating an object directly using any of the available java constructors.
val hashMap = HashMap<String,Int>()
Convert Map to HashMap?
There is no direct extension to convert map to hashmap as it was available in mutable map, so you can :
// Directly use the 4th constructor example
val contact = mapOf("chetan" to "dev.ch8n@gmail.com")
val hashMapOfContact = HashMap(contact)
//Or create and add all entries
val hashMapOfContact = HashMap<String,Int>()
hashMapOfContact.putAll(contact)
TLDR ☕️
Hash Maps:
- They are a direct port of
java.util.HashMap
, whose underlying implementation is based onHashTable
. - Insertion Order is not preserved, because it’s sorted according to
hashcode
of the keys - No special Kotlin standard extension is available over them, you can directly create them using constructor or use standard static factory functions of Kotlin.
- Mutable collection in nature.
Enjoying the Post?
a clap is much appreciated if you enjoyed. No sign up or cost associated :)
If you want to support my content do consider dropping a tip/coffee/donation💰
LinkedHashMap ⛓📝
In Kotlin JVM, similar to HashMap, LinkedHashMap is a type alias for Java’s LinkedHashMap
// Kotlin signature
typealias LinkedHashMap<K, V> = LinkedHashMap<K, V>
// Java signature
class LinkedHashMap<K,V>
extends HashMap<K,V>
implements Map<K,V>
// Available Constructors
Java LinkedHashMap has three constructors
- LinkedHashMap()
- LinkedHashMap(int initialCapacity)
- LinkedHashMap(int initialCapacity,float fillRatio)
- LinkedHashMap(Map<K,V> fromMap)
LinkedHashMap in Java is a Hash table
and LinkedList
based implementation of the (Mutable) Map interface.
- Doubly LinkedList is used to preserve the order of insertion.
- Features are similar to HashMap including methods and constructors.
- Useful to create a
Cache object
that can expire data using some criteria that you define or LRUs ( least recently used ) by overriding theremoveEldestEntry()
Check out my LRU implementation in Repository.

linkedMapOf ️️👷♂️
Kotlin provides two implementations to create LinkedHashMap
// Kotlin Standard Library function
fun <K, V> linkedMapOf(): LinkedHashMap<K, V>
fun <K, V> linkedMapOf(vararg pairs: Pair<K, V>): LinkedHashMap<K, V>
fun <K, V> linkedMapOf(): LinkedHashMap<K, V> = LinkedHashMap<K, V>()
// linkedMapOf directly create LinkedHashMap object default constructor
// Java LinkedHashMap default constructor create LinkedHashMap with
// * inital capacity 16 and * LoadFactor 0.75
fun <K, V> linkedMapOf(vararg pairs: Pair<K, V>): LinkedHashMap<K, V>
= pairs.toMap(LinkedHashMap(mapCapacity(pairs.size)))
// this factory function takes pair and uses LinkedHashMap's second constructor which
// start off with the object capacity as the number of pairs passed
Other way by which you can create a Linkedhashmap
is by creating an object directly using any of the available java constructors.
val linkedHashMap = LinkedHashMap<String,Int>()
Convert Map to LinkedHashMap?
There is no direct extension to convert map
to hashmap
as it was available in mutableMap
, so you can :
// Directly use the 4th constructor example
val contact = mapOf("chetan" to "chetan.garg36@gmail.com")
val linkedMapOfContact = LinkedHashMap(contact)
// Or create and add all entries
val linkedMapOfContact = LinkedHashMap<String,Int>()
linkedMapOfContact.putAll(contact)
Enjoying the Post?
a clap is much appreciated if you enjoyed. No sign up or cost associated :)
If you want to support my content do consider dropping a tip/coffee/donation💰
TLDR ☕️
LinkedHashMaps:
- They are a direct port of
java.util.LinkedHashMap<K,V>
, whose underlying implementation is based onHashTable
andLinkedList
. - Doubly LinkedList is used to preserve the order of insertion
- No special Kotlin standard extension are available over them, you can directly create them using constructors or use standard static factory functions of Kotlin.
- Mutable collection in nature.
Bonus Points: 🤩
Since you made it this far in the post, here is your reward!
Some points that you need to know about maps :
HashMap/LinkedHashMap
- They are not thread-safe, doesn’t have synchronized functions
- The null key is allowed only once
- Performs faster in the multithreaded environment due to lack of synchronization
- They are not a legacy DS, HashMap introduced in 1.2, LinkedHashMap introduced in 1.4
HashTable
- They are thread-safe
- The null key isn’t allowed
- Perform slow in the multithreaded environment due to synchronization
- It is a legacy DS, introduced in 1.0
Conclusion 💆🏻♀️
Hopefully, you understand how Kotlin handles Collection over the JVM platform and some of the key points such as:
- Entries that can’t be directly converted to Map,
- Pair doesn’t have Mutable type,
- It's not always true that your map is a linkedHashMap
- Kotlin JVM resolves Hashmap and LinkedHashMap using Java APIs. etc
Hope you find the post informative, if like more such content you can check more of my blogs.
Until next time, Happy Hacking! 👨🏻💻.
Enjoying the Post?
a clap is much appreciated if you enjoyed. No sign up or cost associated :)
If you want to support my content do consider dropping a tip/coffee/donation💰
Reach me out :
