Коллекции в Kotlin. Изучаем на практике с нуля

kotlin-collections

Коллекции (Collections) - это топовая тема. Несмотря на то, что это всего лишь набор классов с набором функций, программисты постоянно валятся на собеседовании по этой теме. И это вполне справедливо, так как коллекции используются в программировании каждый день. Давайте разбираться на практике, что это такое и как это работает.

Коллекции созданы, что-бы облегчить хранение данных в структурированном виде, а также обеспечить простой способ для манипуляции данными. От части, можно считать, что это аналог массивов, но более расширенный и с дополнительными функциями. Например, массиву необходимо заранее задать размер и изменить его нельзя. Коллекции же умеют хранить любое количество данных, столько сколько нужно в конкретный момент, имеют функционал для манипуляции данными и предлагают различные структуры хранения: список (list), множество (set) или словарь (map).

В видео я на практике показываю, как работать с коллекциями в Kotlin. Рекомендую проделать все тоже самое, что-бы теория из статьи хорошо закрепилась.

Типы коллекций

  • Неизменяемые (read-only). Всю коллекцию необходимо создать сразу, а дальше можно только ее считывать
  • Изменяемые (Mutable). Можно добавлять и удалять элементы коллекции
val list = listOf("one", "two", "three")
// можно только прочитать
val firstElement = list[0]

val mutableList = mutableListOf("one", "two", "three")
// можно прочитать
val firstElement = mutableList[0]
// а еще, можно добавить элемент
mutableList.add("new element")

Иерархия классов коллекций

Если посмотреть на картинку выше, имеем следующее: Есть интерфейс Collection, он содержит базовые методы (правила) для неизменяемой коллекции. Например: чтение данных, получение размера и тд. Интерфейс Collection наследует интерфейс Iterable, который содержит методы (правила) для обхода списочных данных. Это позволяет использовать коллекции в операторах цикла: for, while, do-while. Как работать с циклами, я очень детально рассказал в статье и видео про циклы. А дальше имеем еще два интерфейса: List и Set, которые наследуются от Collection. List и Set - это интерфейсы с методами (правилами) для реализации хранения списочных данных и множества.

Отдельно от всей иерархии классов стоит интерфейс Map. Технически - это не коллекция, так как она не наследуется от Collection. Но это также структура для хранения данных и ее всегда изучают и рассматривают вместе с коллекциями. В разговоре вполне нормально называть Map - коллекцией.

Для Всех интерфейсов коллекции, есть аналог с префиксом Mutable. Такие коллекции изменяемые. Их интерфейсы содержат дополнительные методы для добавления, удаления и других манипуляций с уже созданной коллекцией. Например метод add(), есть только в Mutable коллекции.

Реализации коллекций

List, Set и Map - это всего лишь интерфейсы. В реальном же коде нам необходимы классы, в которых реализуются данные интерфейсы. Реализаций очень много: различные способы хранения данных, потоконебезопасные и потокобезопасные и много других. Но, вот основные, которые используются в 99% случаях:

  • ArrayList - наследуется от интерфейса List. Хранит данные в виде массива, который увеличивается и уменьшается автоматически, в зависимости от количества данных. Доступ к элементу осуществляется по индексу (номеру ячейки).
  • LinkedList - наследуется от интерфейса List. Хранит данные в виде двусвязного списка. Каждый элемент имеет ссылку на предыдущий и на следующий элемент. Доступ к элементу осуществляется по индексу (номеру ячейки). Редко используется, однако его часто спрашивают на собеседовании. LinkedList не доступен по умолчанию в Kolin, но вы можете использовать его из пакета java.util.
  • HashMap - наследуется от интерфейса Map. Хранит значения парами, в виде ключ -> значение. Доступ к элементу осуществляется по ключу. То есть, зная ключ, вы можете получить значение, которое хранится под данным ключем.

HashSet - редко используется поэтому я его не рассматриваю, но его внутреннее устройство аналогично HashMap, за исключением, что в нем хранятся только ключи, значений нет. Так же, есть такие редкие реализации, как TreeSet и TreeMap. Они доступны только из пакета java.util. Данные в них хранятся в виде деревьев и такая структура сортированная в отличии от HashSet и HashMap. Используются они крайне редко.

По умолчанию все реализации коллекций - неизменяемые (read-only). Но, для каждой из них есть вариант с префиксом Mutable - изменяемый.

Неизменяемые коллекции:

// ArrayList
val list = listOf("dsfsdf", "dsfsdfsdf")
// HashSet
val set = setOf("dsfsdf", "dsfsdfsdf")
// HashMap
val map = mapOf("key" to "value", "new key" to "new value")

Изменяемые коллекции:

// ArrayList
val list = mutableListOf("dsfsdf", "dsfsdfsdf")
// HashSet
val set = mutableSetOf("dsfsdf", "dsfsdfsdf")
// HashMap
val map = mutableMapOf("key" to "value", "new key" to "new value")

Обновлено 02 мая 2021

Теги:

"Сайт использует cookie-файлы для того, чтобы вам было удобнее им пользоваться. Для продолжения работы с сайтом, вам необходимо принять использование cookie-файлов."