Question
I have a Kotlin list of strings like this:
val list = listOf("a", "b", "c", "d")
I want to convert this list into a map where the strings become the keys.
I know Kotlin has a toMap() function, but I am not sure how to use it in this case, and I have not found a clear example showing how to convert a List<String> into a Map.
Short Answer
By the end of this page, you will understand how to turn a List into a Map in Kotlin, when to use associate, associateWith, associateBy, and toMap(), and how to choose the right approach depending on the data you have.
Concept
In Kotlin, a List and a Map are different collection types:
- A
Liststores ordered values. - A
Mapstores key-value pairs.
That means a plain list like this:
val list = listOf("a", "b", "c", "d")
cannot become a map by itself unless you decide:
- what the keys should be, and
- what the values should be.
If you want the strings to become the keys, you must also decide what value each key should map to.
For example:
- string → index
- string → same string
- string → length
- string → custom object
This is why toMap() is not usually the first tool for converting a plain List<String> into a Map. The toMap() function is mainly used when your list already contains pairs, such as:
val pairs = listOf(
"a" to 1,
"b" to 2
)
val map = pairs.toMap()
For a regular list, Kotlin provides more direct functions such as:
associate { ... }associateWith { ... }associateBy { ... }
These let you describe how each list item should become a key-value pair.
This matters in real programming because converting lists into maps is common when you want:
- fast lookup by key
- grouped or indexed data
- configuration maps
- API result transformation
- easier access to data by ID, name, or code
Mental Model
Think of a List as a row of items on a shelf:
- position 0 →
"a" - position 1 →
"b" - position 2 →
"c" - position 3 →
"d"
A Map is more like a set of labeled drawers:
- drawer
"a"→ some value - drawer
"b"→ some value - drawer
"c"→ some value
To convert the shelf into labeled drawers, you need to decide two things:
- What label goes on each drawer? The key
- What goes inside each drawer? The value
If your list items themselves are the labels, then you still need to choose the value for each one.
Syntax and Examples
1. Use associateWith when list items should be the keys
If the list values should become the keys, associateWith is often the clearest choice.
val list = listOf("a", "b", "c", "d")
val map = list.associateWith { it.length }
println(map)
Output:
{a=1, b=1, c=1, d=1}
Here:
- each string becomes a key
it.lengthbecomes the value
2. Use associateWith { it } to map each item to itself
val list = listOf("a", "b", "c", "d")
val map = list.associateWith { it }
println(map)
Output:
{a=a, b=b, c=c, d=d}
This creates a map where each string is both the key and the value.
3. Use associate when you want full control over key and value
val list = listOf("a", "b", "c", "d")
val map = list.associate { it to it.uppercase() }
println(map)
Output:
{a=A, b=B, c=C, d=D}
associate is useful when you want to manually create a pair for each element.
4. Use withIndex() if you want the string as key and index as value
val list = listOf("a", "b", "c", "d")
val map = list.withIndex().associate { it.value to it.index }
println(map)
Output:
{a=0, b=1, c=2, d=3}
5. Use toMap() only when you already have pairs
val pairs = listOf(
"a" to 1,
"b" to 2,
"c" to 3
)
val map = pairs.toMap()
println(map)
Output:
{a=1, b=2, c=3}
So toMap() is perfect for List<Pair<K, V>>, but not for a plain List<String> unless you first turn each item into a pair.
Step by Step Execution
Consider this example:
val list = listOf("a", "b", "c")
val map = list.associateWith { it.length }
println(map)
Step by step:
listOf("a", "b", "c")creates a list containing three strings.associateWith { it.length }loops through each item in the list.- For the first item,
itis"a".- key =
"a" - value =
"a".length, which is1
- key =
- For the second item,
itis"b".- key =
"b" - value =
1
- key =
- For the third item,
itis"c".- key =
"c" - value =
1
- key =
- Kotlin builds a map from those key-value pairs.
Final result:
{a=1, b=1, c=1}
Another example using associate:
val list = listOf("a", "b", "c")
val map = list.associate { it to it.repeat(2) }
println(map)
Trace:
"a"becomes"a" to "aa""b"becomes"b" to "bb""c"becomes"c" to "cc"
Result:
{a=aa, b=bb, c=cc}
Real World Use Cases
Converting a list to a map is useful when you want faster access to data by a specific key.
Common use cases
-
User lookup by username
val usernames = listOf("alice", "bob", "carol") val userMap = usernames.associateWith { "active" } -
Product names mapped to prices or IDs
val products = listOf("Pen", "Book", "Bag") val productCodes = products.withIndex().associate { it.value to it.index + 100 } -
API data transformation After fetching a list of objects, you may convert it to a map by ID for quick lookup.
-
Configuration values A list of setting names can be transformed into default values.
-
Caching If you repeatedly search a list for an item by name, converting to a map can improve readability and lookup speed.
Real Codebase Usage
In real Kotlin projects, developers usually convert lists to maps for lookup, validation, and transformation.
Common patterns
Lookup by a unique field
data class User(val id: Int, val name: String)
val users = listOf(
User(1, "Alice"),
User(2, "Bob")
)
val usersById = users.associateBy { it.id }
This is one of the most common patterns in production code.
Build computed values
val words = listOf("cat", "house", "sun")
val wordLengths = words.associateWith { it.length }
Validation and normalization
val fields = listOf("name", "email", "phone")
val validationState = fields.associateWith { false }
Guard against missing keys
Once you have a map, you can safely check values:
if ("email" !in validationState) {
println("Missing field")
}
Preprocessing data for fast access
Instead of repeatedly doing:
users.find { it.id == 2 }
developers often create a map once:
val usersById = users.associateBy { it.id }
val user = usersById[2]
This makes code cleaner and more efficient when repeated lookups are needed.
Common Mistakes
1. Using toMap() on a plain list
This does not work for a List<String> because toMap() expects pairs.
val list = listOf("a", "b", "c")
// val map = list.toMap() // Incorrect
Fix
Use associate, associateWith, or first convert items into pairs.
val map = list.associateWith { it }
2. Forgetting that map values are required
A map always needs both a key and a value.
Broken thinking:
- “I want a map of just keys.”
In Kotlin, that still means you must choose a value.
Possible fixes:
val map1 = list.associateWith { true }
val map2 = list.associateWith { it }
val map3 = list.withIndex().associate { it.value to it.index }
3. Duplicate keys overwrite earlier values
val list = listOf("a", "a", "b")
val map = list.associateWith { it.length }
println(map)
Result:
{a=1, b=1}
Maps cannot store the same key twice. If duplicate keys appear, the last one wins.
4. Confusing associateBy and associateWith
data class User(val id: Int, val name: String)
val users = listOf(User(1, "Alice"), User(2, "Bob"))
associateBy { it.id }→ uses computed key from each elementassociateWith { it.name }→ uses the whole element as the key
Examples:
val byId = users.associateBy { it.id }
val withName = users.associateWith { it.name }
These produce very different maps.
5. Assuming order means index is stored
A map may preserve insertion order in Kotlin implementations, but that does not mean the index becomes the value automatically.
If you want the index, create it explicitly:
val map = list.withIndex().associate { it.value to it.index }
Comparisons
| Function | Best for | Input type | Result example |
|---|---|---|---|
associate | Full control over key and value | Any collection | "a" -> "A" |
associateWith | Element becomes key | Any collection | "a" -> 1 |
associateBy | Computed key from object | Any collection | 1 -> User(...) |
toMap() | Collection already contains pairs | List<Pair<K, V>> | "a" -> 1 |
Example comparison
val words = listOf("cat", "dog")
associateWith
val result = words.associateWith { it.length }
// {cat=3, dog=3}
associate
val result = words.associate { it.first() to it }
// {c=cat, d=dog}
toMap()
val pairs = listOf("cat" to 3, "dog" to 3)
val result = pairs.toMap()
// {cat=3, dog=3}
associateWith vs associateBy
| Function | Key comes from | Value comes from |
|---|---|---|
associateWith | the element itself | lambda result |
associateBy | lambda result | the element itself |
Example:
data class User(val id: Int, val name: String)
val users = listOf(User(1, "Alice"), User(2, "Bob"))
val a = users.associateBy { it.id }
// {1=User(1, Alice), 2=User(2, Bob)}
val b = users.associateWith { it.id }
// {User(1, Alice)=1, User(2, Bob)=2}
Cheat Sheet
// List<String>
val list = listOf("a", "b", "c")
Most useful conversions
// element -> element
val map1 = list.associateWith { it }
// element -> computed value
val map2 = list.associateWith { it.length }
// custom key -> custom value
val map3 = list.associate { it to it.uppercase() }
// element -> index
val map4 = list.withIndex().associate { it.value to it.index }
Use toMap() only for pairs
val pairs = listOf("a" to 1, "b" to 2)
val map = pairs.toMap()
Quick rules
- A
Mapalways has keys and values. List<String>does not directly become a map unless you define values.associateWith= element becomes key.associateBy= lambda result becomes key.toMap()= use when you already havePair<K, V>items.- Duplicate keys overwrite previous values.
Common patterns
val flags = list.associateWith { true }
val selfMap = list.associateWith { it }
val lengths = list.associateWith { it.length }
FAQ
How do I convert a list of strings to a map in Kotlin?
Use associateWith if each string should become a key:
val map = list.associateWith { it.length }
Can I use toMap() on a List<String>?
No. toMap() expects a collection of pairs like List<Pair<K, V>>.
What if I want each string to map to itself?
Use:
val map = list.associateWith { it }
How do I map each string to its index?
Use withIndex() with associate:
val map = list.withIndex().associate { it.value to it.index }
What is the difference between associateBy and associateWith?
associateBy: computes the key, keeps the object as valueassociateWith: keeps the object as key, computes the value
What happens if the list contains duplicate strings?
The later value replaces the earlier one because map keys must be unique.
Which function should beginners use most often?
For this exact problem, associateWith is usually the simplest and clearest choice.
Mini Project
Description
Create a small Kotlin program that converts a list of product names into different maps. This demonstrates the most common collection-to-map transformations developers use: mapping items to themselves, to computed values, and to indexes.
Goal
Build a program that turns a List<String> into several useful Map forms using Kotlin collection functions.
Requirements
- Create a list of at least four product names.
- Build one map where each product name maps to itself.
- Build one map where each product name maps to its length.
- Build one map where each product name maps to its index.
- Print all resulting maps clearly.
Keep learning
Related questions
Accessing Kotlin Extension Functions from Java
Learn how Kotlin extension functions are compiled and how to call them correctly from Java with clear examples and common pitfalls.
Add a Maven Repository URL in Gradle Kotlin DSL (build.gradle.kts)
Learn how to add Maven Central and a custom Maven repository URL in Gradle Kotlin DSL using build.gradle.kts syntax.
Allow HTTP and HTTPS in Android 9 Pie with Network Security Configuration
Learn how Android 9 Pie handles cleartext HTTP traffic and how to allow HTTP and HTTPS safely using network security config.