Convertendo uma lista para mapear no Kotlin
1. Introdução
Neste tutorial rápido, veremos como podemos converter umList em umMap in Kotlin.
2. Implementação
Kotlin oferece o método convenientetoMap que, dada uma lista de objetos complexos, nos permitirá ter elementos em nossa lista mapeados por quaisquer valores que fornecemos:
val user1 = User("John", 18, listOf("Hiking"))
val user2 = User("Sara", 25, listOf("Chess"))
val user3 = User("Dave", 34, listOf("Games"))
@Test
fun givenList_whenConvertToMap_thenResult() {
val myList = listOf(user1, user2, user3)
val myMap = myList.map { it.name to it.age }.toMap()
assertTrue(myMap.get("John") == 18)
}
Lembre-se de que a palavra-chave“to” está sendo usada aqui para criar pares de nomes e idades. Este método deve retornar um mapa que preserva a ordem de entrada dos elementos na matriz:
{John=18, Sara=25, Dave=34}
O mesmo aconteceria quando mapeamos uma matriz menor deString:
@Test
fun givenStringList_whenConvertToMap_thenResult() {
val myList = listOf("a", "b", "c")
val myMap = myList.map { it to it }.toMap()
assertTrue(myMap.get("a") == "a")
}
A única diferença é que não especificamos o valor parait, pois ele só será mapeado por isso.
Então, como uma segunda alternativa para converter aList emMap, é usado o métodoassociatedBy:
@Test
fun givenList_whenAssociatedBy_thenResult() {
val myList = listOf(user1, user2, user3)
val myMap = myList.associateBy({ it.name }, { it.hobbies })
assertTrue(myMap.get("John")!!.contains("Hiking"))
}
Modificamos o teste para que ele use uma matriz como o valor:
{
John=[Hiking, Swimming],
Sara=[Chess, Board Games],
Dave=[Games, Racing sports]
}
3. Qual usar?
Se ambos os métodos alcançam essencialmente a mesma funcionalidade, qual deles devemos usar?
toMap, em termos de implementação, é mais intuitivo. No entanto, usar este método exige que transformemos nossoArray emPairs primeiro, que mais tarde deve ser traduzido para nossoMap, entãothis operation will be particularly useful if we’re already operating on collections of Pairs.
Para coleções de outros tipos, a APIassociate será a melhor escolha.
4. Mapeamento usando métodosassociate*
Em nosso exemplo anterior, usamos o métodoassociateBy, no entanto, o pacote Kotlincollections tem diferentes versões para diferentes casos de uso.
4.1. O Métodoassociate()
Começaremos usando o métodoassociate - que simplesmente retorna umMap usando uma função de transformação nos elementos da matriz:
@Test
fun givenStringList_whenAssociate_thenResult() {
val myList = listOf("a", "b", "c", "d")
val myMap = myList.associate{ it to it }
assertTrue(myMap.get("a") == "a")
}
4.2. O MétodoassociateTo
Usando este método, podemos coletar nossos elementos em um mapa já existente:
@Test
fun givenStringList_whenAssociateTo_thenResult() {
val myList = listOf("a", "b", "c", "c", "b")
val myMap = mutableMapOf()
myList.associateTo(myMap) {it to it}
assertTrue(myMap.get("a") == "a")
}
É importante lembrar de usar oMap – mutável; este exemplo não funcionará com um imutável.
4.3. O MétodoassociateByTo
OassociateByTo nos dá a maior flexibilidade dos três, pois podemos passar o mapa que será preenchido, uma funçãokeySelector. Para cada chave especificada, o valor associado será o objeto de onde a chave foi extraída:
@Test
fun givenStringList_whenAssociateByToUser_thenResult() {
val myList = listOf(user1, user2, user3, user4)
val myMap = mutableMapOf()
myList.associateByTo(myMap) {it.name}
assertTrue(myMap.get("Dave")!!.age == 34)
}
Ou podemos usar uma funçãovalueTransform:
@Test
fun givenStringList_whenAssociateByTo_thenResult() {
val myList = listOf(user1, user2, user3, user4)
val myMap = mutableMapOf()
myList.associateByTo(myMap, {it.name}, {it.age})
assertTrue(myMap.get("Dave") == 34)
}
É importante lembrar queif key collisions happen, only the last added value is retained.
5. Conclusão
Neste artigo, exploramos diferentes maneiras de converter aList em aMap em Kotlin.
Como sempre, a implementação de todos esses exemplos e snippets pode ser encontradaover on GitHub. Este é um projeto baseado em Maven, portanto deve ser fácil importar e executar.