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