Da lista ao mapa: por que isso é importante e como fazer corretamente?
\n\nImagine a situação: você está trabalhando em um aplicativo em Kotlin, recebeu uma lista de usuários de uma API. Você precisa encontrar rapidamente um usuário pelo seu ID. Percorrer a lista toda vez — O(n) —, o que com 1000+ elementos se torna um problema. Já a busca por Map é O(1). A diferença é colossal.
\n\nA pergunta "How to convert List to Map in Kotlin?" é uma das mais populares no Stack Overflow. E não é à toa: uma conversão incorreta pode levar à perda de dados, queda de performance ou bugs estranhos. Hoje vamos analisar 5 formas de transformação, das simples às avançadas, e descobrir como acelerar seu código em 10 vezes.
\n\nAbordagens básicas: associate, toMap e groupBy
\n\n1. Clássico: associate — a escolha mais comum
\nA função associate é o rei da conversão. Ela recebe uma lambda que retorna um par (chave, valor).
data class User(val id: Int, val name: String, val age: Int)\n\nval users = listOf(\n User(1, "Ana", 25),\n User(2, "Boris", 30),\n User(3, "Vitor", 22)\n)\n\n// Caso mais simples: id -> name\nval idToNameMap: Map<Int, String> = users.associate { it.id to it.name }\nprintln(idToNameMap) // {1=Ana, 2=Boris, 3=Vitor}\n\n// Objeto completo por id\nval userMap: Map<Int, User> = users.associate { it.id to it }\nprintln(userMap[2]) // User(id=2, name="Boris", age=30)\n\n\nImportante: se na lista houver chaves duplicadas (associate simplesmente sobrescreverá com a última), você nem perceberá. Fique atento!
2. toMap — quando você já tem uma coleção de pares
\nSe você criou previamente uma lista de pares Pair<K, V>, use toMap().
val pairs = listOf(\n 1 to "Ana",\n 2 to "Boris",\n 3 to "Vitor"\n)\n\nval mapFromPairs: Map<Int, String> = pairs.toMap()\nprintln(mapFromPairs) // {1=Ana, 2=Boris, 3=Vitor}\n\n\ntoMap também funciona com coleções de Map.Entry e outros iteradores de pares.
3. groupBy — quando uma chave corresponde a vários valores
\nÀs vezes é necessário agrupar elementos por chave. Por exemplo, agrupar usuários por idade.
\n\nval usersByAge: Map<Int, List<User>> = users.groupBy { it.age }\n// Resultado: {25=[User(id=1, name=Ana, age=25)], 30=[User(id=2, name=Boris, age=30)], 22=[User(id=3, name=Vitor, age=22)]}\n\n\ngroupBy retorna Map<K, List<V>>. Ideal para análises, filtragem e construção de relatórios.
Técnicas avançadas: quando os métodos padrão não são suficientes
\n\n4. associateBy — se você precisa apenas da chave, e o valor é o próprio elemento
\nA função associateBy é um sinônimo de associate { key to it }, mas é mais legível.
val userMapById: Map<Int, User> = users.associateBy { it.id }\n// Equivalente a: users.associate { it.id to it }\nprintln(userMapById[1]) // User(id=1, name=Ana, age=25)\n\n\nDica: use associateBy quando precisar criar um dicionário "chave → objeto em si". O código fica mais limpo.
5. Conversão personalizada com tratamento de duplicatas
\nSuponha que você tenha uma lista de pedidos, e vários pedidos podem ter o mesmo ID (por exemplo, versões diferentes). O associate padrão simplesmente sobrescreverá. E se você precisar manter todos?
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), // duplicata de id, mas versão diferente\n Order(2, 200.0, 1)\n)\n\n// Opção 1: agrupamento por 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