← Назад к вопросам

С какими коллекциями работал

1.0 Junior🔥 181 комментариев
#Коллекции и структуры данных#Опыт и софт-скиллы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Коллекции в Kotlin и Android

Основные типы коллекций

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

1. List — упорядоченная коллекция с индексами

List — самая часто используемая коллекция. Элементы имеют порядок и доступны по индексу.

// Immutable List
val list: List<String> = listOf("a", "b", "c")
val first = list[0]  // "a"
val size = list.size  // 3
list.forEach { println(it) }  // a, b, c

// Mutable List
val mutableList: MutableList<String> = mutableListOf("a", "b")
mutableList.add("c")
mutableList[0] = "z"  // изменяем элемент
mutableList.remove("b")

// ArrayList — реализация с хорошей производительностью
val arrayList: ArrayList<Int> = arrayListOf(1, 2, 3)
arrayList.add(4)

Производительность:

  • get(index) — O(1) (быстро)
  • add() в конец — O(1)
  • add() в середину — O(n) (медленно)
  • remove() из середины — O(n)

Когда использовать: часто нужен доступ по индексу, частые добавления в конец.

2. Set — уникальные элементы без порядка

Set — коллекция с уникальными элементами. Нет дубликатов и гарантированного порядка.

// Immutable Set
val set: Set<String> = setOf("apple", "banana", "apple")  // apple только один раз
println(set.size)  // 2
println("apple" in set)  // true

// Mutable Set
val mutableSet: MutableSet<String> = mutableSetOf()
mutableSet.add("apple")
mutableSet.add("apple")  // не добавится, уже есть
mutableSet.remove("apple")

// HashSet — O(1) для добавления/поиска
val hashSet: HashSet<Int> = hashSetOf(1, 2, 3, 1)
println(hashSet)  // [1, 2, 3]

// LinkedHashSet — сохраняет порядок добавления
val linkedSet: LinkedHashSet<String> = linkedSetOf("c", "a", "b", "a")
println(linkedSet)  // [c, a, b]

// TreeSet — отсортированный Set (требует Comparator)
val treeSet: TreeSet<Int> = sortedSetOf(3, 1, 2)
println(treeSet)  // [1, 2, 3]

Производительность:

  • add() — O(1) в среднем (O(n) в худшем)
  • contains() — O(1) в среднем
  • remove() — O(1) в среднем

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

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

Map — коллекция пар (key, value). Ключи уникальны.

// Immutable Map
val map: Map<String, Int> = mapOf(
    "apple" to 5,
    "banana" to 3,
    "cherry" to 7
)
val appleCount = map["apple"]  // 5
println(map.size)  // 3

// Mutable Map
val mutableMap: MutableMap<String, Int> = mutableMapOf()
mutableMap["apple"] = 5
mutableMap["banana"] = 3
mutableMap["apple"] = 10  // перезаписываем значение
mutableMap.remove("banana")

// HashMap — O(1) для доступа
val hashMap: HashMap<String, String> = hashMapOf(
    "key1" to "value1",
    "key2" to "value2"
)

// LinkedHashMap — сохраняет порядок вставки
val linkedMap: LinkedHashMap<String, Int> = linkedMapOf(
    "first" to 1,
    "second" to 2
)

// TreeMap — отсортирован по ключам
val treeMap: TreeMap<String, Int> = sortedMapOf(
    "z" to 3,
    "a" to 1,
    "m" to 2
)
println(treeMap)  // {a=1, m=2, z=3}

Работа с Map:

val map = mapOf("a" to 1, "b" to 2, "c" to 3)

// Итерация по entries
for ((key, value) in map) {
    println("$key = $value")
}

// Только ключи
for (key in map.keys) {
    println(key)
}

// Только значения
for (value in map.values) {
    println(value)
}

// Получение с дефолтом
val value = map["d"] ?: 0  // null если нет ключа

// getOrDefault
val value2 = map.getOrDefault("d", 0)

// getOrPut — получить или добавить
val mutableMap = mutableMapOf("a" to 1)
val value3 = mutableMap.getOrPut("b") { 2 }  // добавит b=2 если её нет

Производительность:

  • get() — O(1) в среднем
  • put() — O(1) в среднем
  • remove() — O(1) в среднем

Специальные коллекции для Android

Immutable коллекции (Kotlin collections)

// List, Set, Map по умолчанию immutable
val list = listOf(1, 2, 3)  // нельзя изменять
val set = setOf("a", "b")    // нельзя изменять
val map = mapOf("key" to "value")  // нельзя изменять

SparseArray, LongSparseArray (Android SDK)

Оптимизированные Map для int/long ключей, более экономные по памяти:

// SparseArray<V> — вместо Map<Int, V>
val sparse = SparseArray<String>()
sparse.put(1, "one")
sparse.put(2, "two")
val value = sparse.get(1)  // "one"

// LongSparseArray<V> — для long ключей
val longSparse = LongSparseArray<String>()
longSparse.put(1000L, "thousand")

// ArrayMap<K, V> — для малых maps, меньше памяти
val arrayMap = ArrayMap<String, String>()
arrayMap.put("key", "value")

Фильтрация и трансформация коллекций

val numbers = listOf(1, 2, 3, 4, 5)

// filter — отбор элементов
val evens = numbers.filter { it % 2 == 0 }  // [2, 4]

// map — трансформация
val doubled = numbers.map { it * 2 }  // [2, 4, 6, 8, 10]

// flatMap — map + flatten
val lists = listOf(listOf(1, 2), listOf(3, 4))
val flattened = lists.flatMap { it }  // [1, 2, 3, 4]

// groupBy — группировка
val grouped = numbers.groupBy { it % 2 == 0 }  // {true=[2, 4], false=[1, 3, 5]}

// find — первый элемент
val first = numbers.find { it > 3 }  // 4

// any — есть ли элемент
val hasEven = numbers.any { it % 2 == 0 }  // true

// all — все ли элементы
val allPositive = numbers.all { it > 0 }  // true

// fold — агрегирование
val sum = numbers.fold(0) { acc, num -> acc + num }  // 15

Выбор правильной коллекции

Нужны уникальные элементы?
├─ ДА → Set
│  ├─ Нужен порядок → LinkedHashSet
│  ├─ Нужна сортировка → TreeSet
│  └─ Нужна скорость → HashSet
│
└─ НЕТ (упорядоченная коллекция) → List
   └─ ArrayList (в 99% случаев)

Нужны пары ключ-значение?
├─ ДА → Map
│  ├─ Мало элементов → ArrayMap (Android)
│  ├─ Int/Long ключи → SparseArray (Android)
│  ├─ Нужна сортировка → TreeMap
│  ├─ Нужен порядок вставки → LinkedHashMap
│  └─ Нужна скорость → HashMap
└─ НЕТ → List или Set (выше)

Практический пример в Android

class UserRepository {
    // Кеш пользователей (Map для быстрого поиска по ID)
    private val userCache: MutableMap<Int, User> = HashMap()
    
    // Список всех пользователей (List для порядка)
    private val users: MutableList<User> = mutableListOf()
    
    // Уникальные теги (Set для проверки наличия)
    private val tags: MutableSet<String> = mutableSetOf()
    
    fun getUserById(id: Int): User? {
        return userCache[id]  // O(1)
    }
    
    fun addUser(user: User) {
        users.add(user)  // O(1) в конец
        userCache[user.id] = user  // O(1)
        tags.addAll(user.tags)  // уникальность гарантирована
    }
    
    fun hasTag(tag: String): Boolean {
        return tag in tags  // O(1) проверка
    }
}

Вывод

  • List — для упорядоченных данных, доступа по индексу
  • Set — для уникальных элементов, проверок наличия
  • Map — для пар ключ-значение
  • SparseArray/ArrayMap — оптимизация для Android
  • Выбирай нужную коллекцию в зависимости от задачи
С какими коллекциями работал | PrepBro