Найти тему

Преобразование списка в карту в Kotlin

Оглавление

1. Введение

В этом быстром учебнике мы рассмотрим, как можно преобразовать список в карту в Kotlin.

2. Реализация

В Kotlin доступен удобный метод toMap, который, учитывая список сложных объектов, позволяет нам отобразить элементы в нашем списке по любым предоставленным значениям:

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)
}

Имейте в виду, что ключевое слово "to" используется здесь для создания пар имён и возрастов. Этот метод должен возвращать карту, сохраняя порядок элементов в массиве:

{John=18, Sara=25, Dave=34}

То же самое произойдет, когда мы будем отображать более маленький массив строк:

@Test
fun givenStringList_whenConvertToMap_thenResult() {
val myList = listOf("a", "b", "c")
val myMap = myList.map { it to it }.toMap()

assertTrue(myMap.get("a") == "a")
}

Единственное отличие заключается в том, что мы не указываем значение для него, так как оно будет отображаться только по этому ключу.

Вторым альтернативным способом преобразования списка в карту является использование метода associatedBy:

@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"))
}

Мы модифицировали тест так, чтобы использовать массив в качестве значения:

{
John=[Hiking, Swimming],
Sara=[Chess, Board Games],
Dave=[Games, Racing sports]
}

3. Какой выбрать способ?

Если оба метода в основном достигают одной и той же функциональности, какой из них следует использовать?

Метод toMap с точки зрения реализации более интуитивен. Однако использование этого метода требует преобразования нашего массива сначала в пары, которые затем должны быть преобразованы в нашу карту. Поэтому эта операция будет особенно полезной, если мы уже оперируем коллекциями пар.

Для коллекций других типов API associate будет лучшим выбором.

4. Отображение с использованием методов associate*

В нашем предыдущем примере мы использовали метод associateBy, однако в пакете коллекций Kotlin есть разные версии для различных случаев использования.

4.1 Метод associate()

Мы начнем с использования метода associate, который просто возвращает карту, используя функцию преобразования на элементах массива:

@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 Метод associateTo

С использованием этого метода мы можем собирать наши элементы в уже существующую карту:

@Test
fun givenStringList_whenAssociateTo_thenResult() {
val myList = listOf("a", "b", "c", "c", "b")
val myMap = mutableMapOf<String, String>()

myList.associateTo(myMap) {it to it}

assertTrue(myMap.get("a") == "a")
}

Важно помнить использовать изменяемую карту (mutable Map) - этот пример не будет работать с неизменяемой картой (immutable Map).

4.3 Метод associateByTo

Метод associateByTo предоставляет наибольшую гибкость среди трех, поскольку мы можем передать как карту, которая будет заполнена, так и функцию keySelector. Для каждого указанного ключа связанное значение будет объектом, из которого извлечен ключ:

@Test
fun givenStringList_whenAssociateByToUser_thenResult() {
val myList = listOf(user1, user2, user3, user4)
val myMap = mutableMapOf<String, User>()

myList.associateByTo(myMap) {it.name}

assertTrue(myMap.get("Dave")!!.age == 34)
}

Или мы можем использовать функцию valueTransform:

@Test
fun givenStringList_whenAssociateByTo_thenResult() {
val myList = listOf(user1, user2, user3, user4)
val myMap = mutableMapOf<String, Int>()

myList.associateByTo(myMap, {it.name}, {it.age})

assertTrue(myMap.get("Dave") == 34)
}

Важно помнить, что если происходит коллизия ключей, сохраняется только последнее добавленное значение.

5. Заключение

В данной статье мы рассмотрели различные способы преобразования списка в карту в языке Kotlin.

Оригинал статьи: https://www.baeldung.com/kotlin/list-to-map