Kotlin · 2 / 6

Коллекции, равенство и копирование

Почему val, List и copy не замораживают данные

Ссылка, интерфейс и значение

val запрещает переприсвоение переменной. List<T> предоставляет интерфейс чтения, но за ним может стоять изменяемый объект. Для снимка структуры списка используйте toList(); вложенные объекты при этом остаются общими. Kotlin: коллекции.

val mutable = mutableListOf("draft")
val view: List<String> = mutable
val snapshot = mutable.toList()
mutable += "ready"
println(view.size)     // 2
println(snapshot.size) // 1

Копия модели

Сгенерированный data class.copy() копирует ссылки на поля, а equals учитывает свойства первичного конструктора. Поле, объявленное в теле класса, не становится частью такого равенства. Неизменяемость приходится обеспечивать устройством всей модели. Kotlin: data classes.

data class Cart(val items: MutableList<String>)
val first = Cart(mutableListOf("book"))
val second = first.copy()
second.items += "pen"
println(first.items.size) // 2

Цена ленивости

Sequence выполняет промежуточные операции при терминальном вызове и может остановиться на take. Это экономит ненужную работу, но добавляет накладные расходы. Короткая цепочка маленького списка не обязана ускориться. Эффекты внутри map делают различия порядка вычислений заметными. Kotlin: Sequence.

Для ключа hash-коллекции выбирайте данные с неизменным равенством и хэшем на время хранения. Для массивов сравнивайте содержимое через contentEquals, если нужна семантика значения. Kotlin: equality.

Основа отбора: draft/kotlin_base.md, draft/M++.md, draft/faq500.md.

К вопросам →