Написать пост

Коллекции в Kotlin: знакомство и основные функции

Аватар Azamat Nurkhojayev

Зачем нужны коллекции в Kotlin — List, Set и Map — и как они работают. Как создать редактируемые классы MutableList, MutableSet и MutableMap.

Kotlin — это статически типизированный, объектно-ориентированный язык программирования, работающий поверх JVM (Java Virtual Machine) и разработанный компанией JetBrains.

Kotlin можно использовать везде, где работает Java — а это бэкенд, веб-приложения (как серверная часть, так и интерфейс), десктопные приложения, приложения под Android.

Что же такое коллекция?

Коллекция — это классы-дженерики. Коллекции используются в программировании каждый день.

Коллекции в Kotlin те же самые, что на Java, но с расширением. При создании объекта он либо явно указывается, либо компилятор сам выводит тип составляющих коллекцию объектов.

Для чего же необходимы коллекции? Для того, чтобы облегчить хранение данных.

Виды коллекций

В Kotlin существуют три основных типа коллекций: List, Set и Map.

List хранит и отслеживает позицию элементов. Эта коллекция знает, в какой позиции списка находится тот или иной элемент. Несколько элементов List могут содержать ссылки на один объект.

Set не разрешает дубликаты и не отслеживает порядок, в котором хранятся значения. Коллекция Set не может содержать несколько элементов, ссылающихся на один и тот же объект, или несколько элементов, ссылающихся на два объекта, которые считаются равными.

Map использует пары «ключ-значение». Этот тип коллекции знает, какое значение связано с заданным ключом.

Два ключа могут ссылаться на один объект, но дубликаты ключей невозможны. Хотя ключи обычно представляют собой строковые имена (например, для составления списков свойств в формате»имя-значение«), ключом также может быть произвольный объект.

Простые коллекции являются неизменяемыми. Это значит, что после инициализации вы не сможете добавлять или удалять элементы из коллекции.

Для редактирования коллекций Kotlin представляет изменяемые версии подклассов MutableList, MutableSet и MutableMap.

List и MutableList

Для создания списка List в программе вызывается функция с именем listOf:

			val animals = listOf("Dog", "Cat", "Cow")
		

Компилятор определяет тип объекта, который должен содержаться в списке List, по типам всех значений, переданных при создании.

Также List можно создать явно, указав тип List:

			val animals: List<String> = listOf("Dog", "Cat", "Cow")
		

Для получения элемента вводим:

			if (animals.size > 0) {
  println(animals[0])
  //Получим "Dog"
}
		

Перебор всех элементов List выполняется следующим кодом:

			for (item in animals)
  println (item)
		

Также можно проверить, содержит ли List ссылку на конкретный объект и получить индекс соответствующего элемента.

			if (animals.contains("Cow")) {
  println(animals.indexOf("Cow"))
  //Получим 2
}
		

Если вам нужен список с возможностью обновления элементов, используйте MutableList.

			val animals = mutableListOf("Dog", "Cat")
		

Новые элементы добавляются в MutableList функцией add. При этом новый элемент добавляется в конец списка.

			animals.add("Cow")
		

Если же вы хотите вставить значение в позицию с конкретным индексом, передайте индекс функции наряду со значением.

			animals.add(1, "Cow")
		

Есть два способа удаления значений из MutableList.

В первом способе вызывается функция remove, которой передается удаляемое значение. Например, следующий код проверяет, содержит ли список animals строку «Cow», после чего удаляет соответствующий элемент:

			if (animals.contains("Cow")) {
  animals.remove("Cow")
}
		

Второй способ основан на использовании функции removeAt для удаления значения с заданным индексом:

			if (animals.size > 1) {
  animals.removeAt(1)
}
		

Если вы хотите обновить MutableList так, чтобы значение с конкретным индексом было заменено другим значением, это можно сделать при помощи функции set:

			if (animals.size > 0) {
  animals.set(0, "Cow")
}
		

Прочие функции MutableList:

  1. sort — возвращает список List и сортирует содержимое MutableList в естественном порядке;
  2. reverse — возвращает список List и переставляет элементы в обратном порядке;
  3. shuffle — возвращает список List и сгенерирует случайную перестановку;
  4. addAll — добавляет все элементы, хранящиеся в другой коллекции;
  5. removeAll — удаляет элементы, входящие в другую коллекцию;
  6. retainAll — оставляет все элементы, входящие в другую коллекцию, и удаляет все остальные;
  7. clear — удаляет все элементы.

Set и MutableSet

Если вам нужна коллекция, которая не допускает дублирования, используйте Set: неупорядоченную коллекцию без повторяющихся значений.

В отличие от List, множество Set не упорядочено и не может содержать повторяющихся значений.

В Set не может быть дубликатов: при попытке создания дублирующих элементов Set будет игнорировать их.

Для создания списка Set в программе вызывается функция с именем setOf:

			val animalsSet = setOf("Dog", "Cat", "Cow")

\ Указываем тип явно
val animalsSet:Set<String> = setOf("Dog", "Cat", "Cow")
		

Перебор элементов множества Set в цикле:

			for (item in animalsSet)
  println(item)
		

Функция contains возвращает true, если содержит элемент, и false в противном случае.

Множество Set неизменяемо — в него нельзя добавлять новые или удалять существующие значения. Для выполнения таких операций используется класс MutableSet.

Функции MutableSet:

  1. add — добляет элемент;
  2. remove — удаляет элемент;
  3. clear — удаление всех элементов;
  4. функции addAll, removeAll и retainAll также могут использоваться для внесения массовых изменений в MutableSet (по аналогии с MutableList).

Map и MutableMap

Коллекция Map работает как список свойств. Вы передаете ей ключ, а Map возвращает значение, связанное с этим ключом. Хотя ключи обычно имеют тип String, они могут быть объектами любого типа.

Каждый элемент Map состоит из двух объектов — ключа и значения. С каждым ключом связывается одно значение. В коллекции могут присутствовать повторяющиеся значения, но не повторяющиеся ключи.

Чтобы создать Map, вызовите функцию с именем mapOf и передайте ей пары «ключ-значение» для инициализации Map.

			data class Recipe(val s: String)

val r1 = Recipe("Pizza")
val r2 = Recipe("Burger")
val r3 = Recipe("Taco")
//Каждый элемент определяется в форме «ключ-значение». Ключи обычно
//являются строками, как в данном примере.
val recipeMap = mapOf("Recipe1" to r1, "Recipe2" to r2, "Recipe3" to r3)

// Явно определяем типы
val recipeMap: Map<String, Recipe> = mapOf("Recipe1" to r1, "Recipe2" to r2, "Recipe3" to r3)
		

С Map чаще всего выполняются три операции: проверка наличия конкретного ключа или значения, выборка значения для заданного ключа и перебор всех элементов Map.

Для проверки наличия конкретного ключа или значения в Map используются его функции containsKey и containsValue:

			//код проверяет, содержит ли Map с именем recipeMap ключ «Recipe1»
recipeMap.containsKey("Recipe1")

//код проверяет, содержит ли Map recipeMap значение toCheck
val toCheck = Recipe("Pizza")
if (recipeMap.containsValue(recipeToCheck)) {
//Код, выполняемый при наличии значения в Map
}
		

Для получения значения, связанного с конкретным ключом, используются функции get и getValue. Если заданный ключ не существует, get возвращает null, а getValue вызывает исключение.

Также вы можете перебрать все элементы Map. Например, вот как цикл for используется для вывода всех пар «ключ-значение» в recipeMap:

			for ((key, value) in recipeMap) {
  println("Key is $key, value is $value")
}

> Key is Recipe1, value is Recipe(s=Pizza)
> Key is Recipe2, value is Recipe(s=Burger)
> Key is Recipe3, value is Recipe(s=Taco)
		

Объект Map неизменяем, поэтому вы не сможете добавлять или удалять пары «ключ-значение», а также обновлять значение, хранящееся для заданного ключа. Для выполнения такой операции следует использовать класс MutableMap. Посмотрим, как он работает.

Давайте создадим MutableMap:

			val r1 = Recipe("Pizza")
val r2 = Recipe("Burger")

val recipeMap = mutableMapOf("Recipe1" to r1, "Recipe2" to r2)
		

Для добавления элементов в MutableMap используется функция put:

			val r3 = Recipe("Taco")
recipeMap.put("Recipe3", r3)
		

Также в MutableMap можно добавить сразу несколько пар «ключ-значение» при помощи функции putAll:

			val r4 = Recipe("Coffee")
val r5 = Recipe("Tea")

val toAdd = mapOf("Recipe4" to r4, "Recipe5" to r5)
recipeMap.putAll(toAdd)
		

Удаление элемента с ключом с помощью remove уничтожит все элементы с clear:

			recipeMap.remove("Recipe2")
recipeMap.clear()
		

Еще можно удалить их таким способом:

			val toRemove = Recipe("Burger")
recipeMap.remove("Recipe2", toRemove)
//Удаление элемента с ключом «Recipe2», но только в том случае, если его
//значением является объект Recipe("Burger")
		

Надеюсь, что вам была полезна эта статья, а я смог верно передать информацию о коллекциях в Kotlin, об основных видах коллекций и функциях.

Следите за новыми постами
Следите за новыми постами по любимым темам
13К открытий13К показов