---
title: Структуры данных
seo:
  title: Структуры данных — Kotlin Developer
  description: "Тема «Структуры данных» для собеседования Kotlin Developer. В чём различия между стеком и кучей? Какие структуры данных вы знаете, для чего они используются и в каких случаях их следует применять?"
---

[Все темы Kotlin Developer](/kotlin-developer)

## <strong>В чём различия между стеком и кучей?</strong> [#q-14bee738d69b8196bc61da2357a18a4e]

Стек и куча - это два основных механизма управления памятью&#58;

{/* prettier-ignore */}
1. <strong>Стек</strong> <code>&#40;Stack&#41;</code>&#58;

    - Хранит локальные переменные и вызовы функций.

    - Организуется по принципу LIFO (Last-In, First-Out).

    - Размер стека фиксирован и обычно небольшой.

    - Управление стеком автоматическое и эффективное.

1. <strong>Куча</strong> <code>&#40;Heap&#41;</code>&#58;

    - Используется для динамического выделения памяти.

    - Объекты хранятся в куче, когда их размер неизвестен на этапе компиляции или когда они должны быть доступны в течение продолжительного времени.

    - Управление памятью в куче более сложное, и она может подвергаться фрагментации.

    - В Kotlin/JVM память объектов в куче освобождает GC. Разработчик управляет достижимостью объектов и отдельно закрывает внешние ресурсы, например файлы.

:::note[Ссылки для изучения]

1. [Типы данных в Kotlin](https://metanit.com/kotlin/tutorial/2.2.php)
   :::

---

## <strong>Какие структуры данных вы знаете, для чего они используются и в каких случаях их следует применять?</strong> [#q-14bee738d69b81f99d32f0d3de8146f5]

Вот несколько основных структур данных и их области применения&#58;

{/* prettier-ignore */}
1. <strong>Список</strong> <code>&#40;List&#41;</code>&#58;

    - Позволяет хранить упорядоченную коллекцию элементов.

    - Используется для хранения данных, которые должны быть упорядочены и доступны для изменения.

1. <strong>Массив</strong> <code>&#40;Array&#41;</code>&#58;

    - Представляет собой последовательный блок памяти, содержащий элементы одного типа данных.

    - Эффективен для доступа к элементам по индексу.

    - Часто используется в алгоритмах и задачах, где требуется быстрый доступ к элементам.

1. <strong>Стек</strong> <code>&#40;Stack&#41;</code>&#58;

    - Реализует принцип Last-In, First-Out (LIFO).

    - Используется для управления вызовами функций, обратного отслеживания, обхода деревьев и т. д.

1. <strong>Очередь</strong> <code>&#40;Queue&#41;</code>&#58;

    - Реализует принцип First-In, First-Out (FIFO).

    - Используется в задачах, где необходимо обрабатывать элементы в том порядке, в котором они были добавлены.

1. <strong>Словарь</strong> <code>&#40;Dictionary или Map&#41;</code>&#58;

    - Предоставляет связь между ключами и значениями.

    - Используется для быстрого доступа к данным по ключу и поиска элементов по ключу.

1. <strong>Множество</strong> <code>&#40;Set&#41;</code>&#58;

    - Содержит уникальные элементы без учета порядка.

    - Используется для удаления дубликатов и проверки на принадлежность элемента к набору.

1. <strong>Связанный список</strong> <code>&#40;Linked List&#41;</code>&#58;

    - Элементы связаны ссылками. Доступ по индексу требует обхода списка и занимает O(n).

    - Вставка и удаление рядом с уже найденным узлом эффективны; поиск позиции в середине списка сам по себе занимает O(n).

:::note[Ссылки для изучения]

1. [Типы данных в Kotlin](https://metanit.com/kotlin/tutorial/2.2.php)
   :::

---

## <strong>Какие структуры данных наиболее часто используются в Kotlin и как они реализованы?</strong> [#q-14bee738d69b8164bbb8d4e1228a4226]

Наиболее часто используемые структуры данных в Kotlin&#58;

- List&#58; Интерфейс списка только для чтения, например List&#60;Int&#62;. Сам объект может изменяться через другую ссылку.

- <code>MutableList</code>&#58; Реализован как изменяемый список. Например,
  <code>MutableList&#60;Int&#62;</code>.

- Set&#58; Интерфейс множества только для чтения, например Set&#60;Int&#62;. Сам объект может изменяться через другую ссылку.

- <code>MutableSet</code>&#58; Реализован как изменяемое множество. Например,
  <code>MutableSet&#60;Int&#62;</code>.

- Map&#58; Интерфейс словаря только для чтения, например Map&#60;String, Int&#62;. Сам объект может изменяться через другую ссылку.

- <code>MutableMap</code>&#58; Реализован как изменяемый словарь. Например,
  <code>MutableMap&#60;String&#44; Int&#62;</code>.

Все эти интерфейсы позволяют читать и искать элементы. Операции добавления, удаления и замены предоставляют изменяемые интерфейсы MutableList, MutableSet и MutableMap.

:::note[Ссылки для изучения]

1. [Типы данных в Kotlin](https://metanit.com/kotlin/tutorial/2.2.php)
   :::

---

## <strong>Объясните разницу между</strong> <code>MutableList</code> <strong>и</strong> <code>List</code> <strong>в Kotlin.</strong> [#q-14bee738d69b812f99c5debf4545897c]

Разница между <code>MutableList</code> и <code>List</code>&#58;

- List предоставляет доступ только для чтения. Через эту ссылку нельзя добавлять, удалять или заменять элементы, но другой владелец MutableList может изменить тот же объект. Пример&#58; val numbers&#58; List&#60;Int&#62; = listOf(1, 2, 3).

- <strong>MutableList</strong>&#58; Изменяемый список. Позволяет добавлять,
  удалять и изменять элементы после создания. Пример&#58;
  <code>
    val mutableNumbers&#58; MutableList&#60;Int&#62; &#61;
    mutableListOf&#40;1&#44; 2&#44; 3&#41;
  </code>
  .

:::note[Ссылки для изучения]

1. [Типы данных в Kotlin](https://metanit.com/kotlin/tutorial/2.2.php)
   :::

---

## <strong>Как реализовать собственную структуру данных в Kotlin?</strong> [#q-14bee738d69b81d78e23c600f5d83b21]

Чтобы реализовать собственную структуру данных, необходимо создать класс и определить нужные методы.
Пример — реализация простого стека&#58;

```kotlin
class Stack<T> {
    private val elements = mutableListOf<T>()

    fun push(item: T) {
        elements.add(item)
    }

    fun pop(): T? {
        if (elements.isEmpty()) {
            return null
        }
        return elements.removeAt(elements.size - 1)
    }

    fun isEmpty() = elements.isEmpty()

    fun size() = elements.size
}
```

:::note[Ссылки для изучения]

1. [Типы данных в Kotlin](https://metanit.com/kotlin/tutorial/2.2.php)
   :::

---

## <strong>В каких случаях стоит использовать</strong> <code>HashMap</code> <strong>вместо</strong> <code>TreeMap</code><strong>?</strong> [#q-14bee738d69b81a191a0d2b93ddeba0e]

Разница между <code>HashMap</code> и <code>TreeMap</code>&#58;

- HashMap подходит для доступа по ключу без сортировки. При хорошем распределении хешей get и remove имеют ожидаемую сложность O(1), а put также требует учитывать амортизированную стоимость расширения. Это не безусловная гарантия для худшего случая. Порядок обхода не гарантируется.

- <code>TreeMap</code>&#58; Используется, когда требуется хранить элементы в
  отсортированном порядке. TreeMap реализует красно-черное дерево и обеспечивает
  логарифмическую сложность для операций вставки, удаления и поиска.
  Поддерживает упорядоченные итерации.

В общем, используйте <code>HashMap</code> для быстрых операций с элементами без необходимости в сортировке, и <code>TreeMap</code> — когда необходима сортировка и упорядоченный доступ.

:::note[Ссылки для изучения]

1. [Типы данных в Kotlin](https://metanit.com/kotlin/tutorial/2.2.php)
   :::
