Kotlin предлагает два типа коллекций: immutable (неизменяемые) и mutable (изменяемые).
List — неизменяемый список. Добавлять/удалять элементы нельзя.MutableList — изменяемый список: можно добавлять и удалять элементы.Set — неизменяемое множество (уникальные элементы).MutableSet — изменяемое множество.Map — ассоциативный массив (ключ-значение), неизменяемый.MutableMap — изменяемый ассоциативный массив.val fruits: List<String> = listOf("Apple", "Banana", "Cherry") val mutableFruits: MutableList<String> = mutableListOf("Apple", "Banana") mutableFruits.add("Cherry") val fruitSet: Set<String> = setOf("Apple", "Banana") // Уникальность элементов val mutableFruitSet: MutableSet<String> = mutableSetOf("Apple", "Banana") mutableFruitSet.add("Cherry") val scores: Map<String, Int> = mapOf("Tom" to 80, "Jane" to 90) val mutableScores: MutableMap<String, Int> = mutableMapOf("Tom" to 80) mutableScores["Jane"] = 90
Тонкости:
List (а не MutableList).Если у вас есть функция, принимающая
List<T>как параметр, можете ли вы каким-либо образом изменить этот список внутри функции?
Ответ: Нет, если параметр типа List<T>, то внутри функции нельзя добавить/удалить элементы. Но если фактически передан MutableList<T>, его можно привести к этому типу (что привносит риск):
fun modifyList(list: List<String>) { if (list is MutableList) { list.add("Another") // Работает, если исходная коллекция изменяемая } }
Так делать не рекомендуется, так как нарушается контракт (List должен быть неизменяемым!).
История
В крупном проекте использовали функцию, принимающую
List<Customer>, и пытались добавить в неё новый элемент внутри функции. Ошибка компиляции (add/clear/remove не определены для List) была обнаружена только при ревью, т.к. требовался именно изменяемый список для преобразования данных.
История
Коллекция была объявлена как
MutableList, но передавалась в несколько потоков без синхронизации. В итоге возникали конкурирующие изменения, приводившие к "ConcurrentModificationException" и порче состояния списка. Ошибку искали долго, не приняли во внимание thread-safety.
История
В одном из сервисов для работы с результатами выборок из БД использовали
mutableListOf, потом отдавали ссылку наружу. Сторонний код по ошибке очищал список. В результате до пользователя доходили пустые данные, т.к. ссылки не клонировались и mutable коллекции модифицировались за пределами слоя бизнес-логики.