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

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

1. Вступление

В этом кратком руководстве мы увидим, как преобразоватьList вMap in 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}

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

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

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

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

Затем в качестве второй альтернативы преобразованиюList вMap можно использовать метод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, с точки зрения реализации, более интуитивно понятен. Однако использование этого метода требует, чтобы мы сначала преобразовали нашArray вPairs, который позже должен быть переведен в нашMap, поэтомуthis operation will be particularly useful if we’re already operating on collections of Pairs.

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

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

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

4.1. Методassociate()

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

@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()

    myList.associateTo(myMap) {it to it}

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

Важно помнить, что использовать изменяемыйMap –: этот пример не будет работать с неизменяемым.

4.3. МетодassociateByTo

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

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

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

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

Важно помнить, чтоif key collisions happen, only the last added value is retained.

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

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

Как всегда, реализацию всех этих примеров и фрагментов можно найти вover on GitHub. Это проект на основе Maven, поэтому его легко импортировать и запускать.