List, Set и Map

Знакомимся с тремя основными видами коллекций.

Коллекция — объект, который хранит группу элементов; в Kotlin основные виды — List, Set и Map.

Хранить наборы данных приходится постоянно. Kotlin предлагает три типа коллекций, и у каждого есть две версии: read-only (только чтение) и mutable (изменяемая).

List — упорядоченный список

List хранит элементы по порядку и допускает повторы; доступ к элементу — по индексу с нуля.

fun main() {
    val fruits = listOf("яблоко", "банан", "яблоко")
    println(fruits[0])
    println(fruits.size)
    println("банан" in fruits)
}

Вывод:

яблоко
3
true

Set — множество без дублей

Set хранит только уникальные элементы: повторы автоматически отбрасываются. Порядок в обычном Set не гарантирован.

fun main() {
    val numbers = setOf(1, 2, 2, 3, 3, 3)
    println(numbers)
    println(numbers.size)
}

Вывод:

[1, 2, 3]
3

Map — пары ключ-значение

Map сопоставляет ключам значения. Доступ — по ключу в квадратных скобках.

fun main() {
    val ages = mapOf("Аня" to 25, "Боря" to 30)
    println(ages["Аня"])
    for ((name, age) in ages) {
        println("$name: $age")
    }
}

Вывод:

25
Аня: 25
Боря: 30

Изменяемые версии

Функции listOf, setOf, mapOf создают read-only коллекции — добавить элемент в них нельзя. Для изменяемых есть mutableListOf, mutableSetOf, mutableMapOf.

fun main() {
    val list = mutableListOf(1, 2)
    list.add(3)
    list.remove(1)
    println(list)
}

Вывод:

[2, 3]

Как работает под капотом

«Read-only» в Kotlin означает, что у интерфейса List просто нет методов изменения (вроде add) — но это не «глубокая заморозка». Если такую коллекцию передать в Java-код, оттуда её теоретически могут изменить, ведь под капотом это тот же ArrayList. Тем не менее в Kotlin-коде разделение на List и MutableList очень помогает: тип сразу сообщает, можно ли менять коллекцию.

Частые ошибки

  • Пытаться вызвать add у listOf. Это read-only коллекция; нужен mutableListOf.
  • Ждать порядок от Set. Обычное множество не гарантирует порядок элементов.
  • Обращаться к Map по индексу. map[ключ] — это доступ по ключу, а не по позиции.

Итог

  • List — упорядочен, допускает повторы, доступ по индексу.
  • Set — только уникальные элементы.
  • Map — пары ключ-значение, доступ по ключу.
  • У каждого вида есть read-only и mutable версии.
Проверьте себя
1. Чем Set отличается от List?
ASet хранит пары ключ-значение
BSet хранит только уникальные элементы, без дублей
CSet всегда отсортирован по возрастанию
DМежду ними нет разницы
2. Что произойдёт при вызове add у коллекции, созданной через listOf?
AЭлемент добавится
BОшибка компиляции: listOf создаёт read-only список
CСписок очистится
DСоздастся новый список
3. Как получить значение по ключу "Аня" из mapOf("Аня" to 25)?
Aages.get(0)
Bages["Аня"]
Cages.Аня
Dages.value("Аня")