Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Map is a commonly used data structure in Kotlin for manipulating key-value associations.
In this quick tutorial, let’s explore how to convert a Map to Lists in Kotlin.
A Map carries key-value associations. When we talk about converting a Map to Lists, there could be two cases:
Moreover, considering the “two lists” case carefully, we can cover another two scenarios. The simplest scenario involves obtaining separate key and value lists without preserving their original key-value associations within the map.
However, sometimes, we want the converted key list and the value list to be correlated. In other words, given an index i, the elements keyList[i] and valueList[i] are still associated as they were in the original map:
Map:
k1 -> v1
k2 -> v2
k3 -> v3
index : 0, 1, 2
keyList : k1, k2, k3
valueList: v1, v2, v3
We’ll discuss converting a map to lists, covering all the scenarios mentioned above.
So first, let’s create a Kotlin Map object as the input example:
val DEV_MAP: Map<String, String> = mapOf(
"Kent" to "Linux",
"Eric" to "MacOS",
"Kevin" to "Windows",
"Michal" to "MacOS",
"Saajan" to "Linux",
)
As the code above shows, we initialized a Map using the mapOf() function. The map stores five developers and the primary operating systems they use.
Next, we’ll convert this DEV_MAP to lists. Additionally, to ensure clarity and verification, we’ll use unit test assertions to verify whether each approach produces the expected result.
First, let’s convert DEV_MAP to one list.
In Kotlin, map.entries gives us a read-only Set of all entries in the map. Then, we can use toList() to convert the set to a list:
val result = DEV_MAP.entries.toList()
assertEquals(DEV_MAP.size, result.size)
result.forEach { entry ->
assertEquals(DEV_MAP[entry.key], entry.value)
}
Alternatively, the map.toList() function returns a list of key-value Pairs. Therefore, we can get List<Pair<String, String>> by simply calling DEV_MAP.toList():
val result = DEV_MAP.toList()
assertEquals(DEV_MAP.size, result.size)
result.forEach { pair ->
assertEquals(DEV_MAP[pair.first], pair.second)
}
In this section, let’s delve into converting a map into separate key and value lists. Additionally, we’ll explore techniques for maintaining the relationship between these key and value lists intact.
It would be a simple task if we merely aimed to obtain key and value lists from a map without concern for retaining the initial key-value pair associations. This is because Kotlin’s Map provides the keys and values properties, which return a Set of keys and a Collection of values, respectively. What we need to do is convert them to lists using the handy toList() function:
val keyList = DEV_MAP.keys.toList()
val valueList = DEV_MAP.values.toList()
assertThat(keyList).containsExactlyInAnyOrder("Kent", "Eric", "Kevin", "Michal", "Saajan")
assertThat(valueList).containsExactlyInAnyOrder("Linux", "MacOS", "Windows", "MacOS", "Linux")
The first idea that comes up to get correlated key and value lists might be iterating through the map entries and filling each entry’s key and value in two pre-initialized key and value lists:
val keyList = mutableListOf<String>()
val valueList = mutableListOf<String>()
DEV_MAP.entries.forEach {
keyList += it.key
valueList += it.value
}
assertThat(keyList).hasSize(DEV_MAP.size)
assertThat(valueList).hasSize(DEV_MAP.size)
//verify correlation
repeat(DEV_MAP.size) { idx -> assertEquals(DEV_MAP[keyList[idx]], valueList[idx]) }
In the code above, it’s worth noting that we used the MutableList‘s plusAssign operator (+=) to add an element to the list.
Alternatively, we can transform the map into a Pair of correlated keyList and valueList. This approach doesn’t require pre-initializing the two lists:
val (keyList, valueList) = DEV_MAP.toList().let { kvpList -> kvpList.map { it.first } to kvpList.map { it.second } }
assertThat(keyList).hasSize(DEV_MAP.size)
assertThat(valueList).hasSize(DEV_MAP.size)
repeat(DEV_MAP.size) { idx -> assertEquals(DEV_MAP[keyList[idx]], valueList[idx]) }
Next, let’s understand how this one-liner works.
We’ve learned that DEV_MAP.toList() returns a list of key and value pairs. The let{} function transformed List<Pair<key, value>> into Pair<keyList, valueList>. Then, we used Kotlin’s deconstructing declaration to assign the two lists in the pair to two list variables.
In this article, we initially discussed different problem scenarios involving the conversion of a map into lists. Then, we explored how to solve the problem in each scenario through examples.