Освой Kotlin играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
В 2018 году в androidx появился новый пакет collection, который содержал несколько специфичных структур данных, переписанных на Kotlin, таких как LongSparseArray, SimpleArrayMap и SparseArrayCompat.
В январе 2024 года был выпущена новая версия библиотеки с заменой HashMap.
dependencies {
implementation("androidx.collection:collection:1.4.0")
}
Зависимость можно не прописывать явно сейчас, всё может работать и так.
Следует сказать, что данные коллекции эффективны при очень больших объёмах. В стандартных случаях особого выигрыша нет. Поэтому в реальных примерах классы из данной библиотеки не часто встречаются. Поэтому рассказ о них будет минимальным.
// обобщённая реализация
val cats = objectListOf("Барсик", "Мурзик", "Рыжик")
val dogs = objectListOf("Шарик", "Тузик")
val catsAndDogs = mutableObjectListOf<String>()
// переопределённые операторы plusAsssign
catsAndDogs += dogs
catsAndDogs += cats
catsAndDogs += "Васька"
catsAndDogs += "Полкан"
// изменяемая версия mutableIntListOf()
val fibonacciIntegerNumbers = intListOf(1, 1, 2, 3, 5)
// изменяемая версия mutableLongListOf()
val fibonacciLongNumbers = longListOf(1, 1, 2, 3, 5)
// изменяемая версия mutableFloatListOf()
val fibonacciFloatingNumbers = floatListOf(1f, 1f, 2f, 3f, 5f)
Коротко о классах, используемых в примере выше.
Библиотека включает три реализации пар значений для примитивных типов.
IntIntPair хранит два значения типа Int в виде одного числа Long благодаря простейшей битовой математики: первое число хранится в старших 32 битах Long, а второе в младших.
FloatFloatPair хранит два значения типа Float в одном значении типа Long, отличие заключается только в дополнительной трансформации числа Float в битовое представление типа Int.
LongLongPair - простейшая реализация для двух чисел типа Long.
ScatterMap является новой реализацией HashMap.
// обобщённый вариант хэш-таблицы
val scatterMap: ScatterMap<String, String> = mutableScatterMapOf()
// реализации хэш-таблиц для примитивных типов, аналогичные варианты есть для Long и Float
intIntMapOf()
intFloatMapOf()
intLongMapOf()
intObjectMapOf<String>()
// варианты для случаев, когда в качестве ключа один из примитивных типов: Int, Long или Float
intObjectMapOf<String>()
longObjectMapOf<String>()
floatObjectMapOf<String>()
/* похожие варианты на intIntMapOf(), intLongMapOf() и intObjectMapOf()
есть в android.util пакете - SparseIntArray, SparseLongArray
и SparseArray соответственно */
Появилось новое множество ScatterSet.
SparseArrayCompat, LongSparseArray, SimpleArrayMap, ArraySet и LruCache - переписанные версии из пакета android.util на Kotlin.
CircularArray и CircularIntArray - динамические массивы с возможностью добавить значение в начало и в конец за O(1) время, реализация основана на двух индексах head и tail, которые перемещаются по массиву в противоположных направлениях: первый уменьшается, а второй увеличивается, при совпадении индексов массив удваивается.