From List to Map: Why It Matters and How to Do It Right?
\n\nImagine a scenario: you're working on a Kotlin application and you've received a list of users from an API. You need to quickly find a user by their ID. Iterating through the list each time is O(n), which becomes painful with 1000+ elements. But searching by Map is O(1). The difference is colossal.
\n\nThe question "How to convert List to Map in Kotlin?" is one of the most popular on Stack Overflow. And for good reason: incorrect conversion can lead to data loss, performance degradation, or strange bugs. Today we'll break down 5 transformation methods, from simple to advanced, and learn how to speed up your code by 10 times.
\n\nBasic Approaches: associate, toMap, and groupBy
\n\n1. The Classic: associate — The Most Common Choice
\nThe associate function is the king of conversion. It takes a lambda that returns a pair (key, value).
data class User(val id: Int, val name: String, val age: Int)\n\nval users = listOf(\n User(1, "Anna", 25),\n User(2, "Boris", 30),\n User(3, "Victor", 22)\n)\n\n// Simplest case: id -> name\nval idToNameMap: Map<Int, String> = users.associate { it.id to it.name }\nprintln(idToNameMap) // {1=Anna, 2=Boris, 3=Victor}\n\n// Full object by id\nval userMap: Map<Int, User> = users.associate { it.id to it }\nprintln(userMap[2]) // User(id=2, name="Boris", age=30)\n\n\nImportant: if there are duplicate keys in the list (associate simply overwrites with the last one), you won't even notice. Be careful!
2. toMap — When You Already Have a Collection of Pairs
\nIf you've pre-created a list of Pair<K, V>, use toMap().
val pairs = listOf(\n 1 to "Anna",\n 2 to "Boris",\n 3 to "Victor"\n)\n\nval mapFromPairs: Map<Int, String> = pairs.toMap()\nprintln(mapFromPairs) // {1=Anna, 2=Boris, 3=Victor}\n\n\ntoMap also works with collections of Map.Entry and other pair iterators.
3. groupBy — When One Key Corresponds to Multiple Values
\nSometimes you need to group elements by a key. For example, group users by age.
\n\nval usersByAge: Map<Int, List<User>> = users.groupBy { it.age }\n// Result: {25=[User(id=1, name=Anna, age=25)], 30=[User(id=2, name=Boris, age=30)], 22=[User(id=3, name=Victor, age=22)]}\n\n\ngroupBy returns Map<K, List<V>>. Perfect for analytics, filtering, and report building.
Advanced Techniques: When Standard Methods Aren't Enough
\n\n4. associateBy — If You Only Need the Key, and the Value Is the Element Itself
\nThe associateBy function is a synonym for associate { key to it }, but reads better.
val userMapById: Map<Int, User> = users.associateBy { it.id }\n// Equivalent to: users.associate { it.id to it }\nprintln(userMapById[1]) // User(id=1, name=Anna, age=25)\n\n\nTip: use associateBy when you need to create a "key → object itself" dictionary. The code becomes cleaner.
5. Custom Conversion with Duplicate Handling
\nSuppose you have a list of orders, and several orders can have the same ID (e.g., different versions). Standard associate simply overwrites. But what if you need to keep all of them?
data class Order(val id: Int, val amount: Double, val version: Int)\n\nval orders = listOf(\n Order(1, 100.0, 1),\n Order(1, 150.0, 2), // duplicate id, but different version\n Order(2, 200.0, 1)\n)\n\n// Option 1: grouping by id\nval ordersGrouped: Map<Int, List<Order>> = orders.groupBy { it.id }\n// {1=[Order(1, 100.0, 1), Order(1, 150.0, 2)], 2=[O