Collection

https://kotlinlang.org/docs/collections-overview.html
https://kotlinlang.org/docs/constructing-collections.html
https://kotlinlang.org/docs/iterators.html

Collections

Коллекции - контейнеры для хранения данных.

• kotlin полагается на коллекции Java.

• делятся на mutable и immutable.

Iterable

Находится на вершине коллекций. Все изменяемый коллекции реализуют интерфейс MutableIterable - он представляет функцию итератора для перебора коллекции.

Collection

Для изменения данных определен интерфейс MutableCollection наследуется от Collection и предоставляет методы для удаления и добавления элементов.

add добавляет элемент.

remove удаляет элемент.

addAll добавляет набор элементов.

removeAll удаляет набор элементов.

clear удаляет все элементы из коллекции.

List

Представляет обычный список на основе массива.

val list: List<String> = listOf("Tom", "Sam", "Bob", "Mike")
MutableList

Изменяемый список. Под капотом ArrayList.

val list: MutableList<String> = mutableListOf("Tom", "Sam", "Bob", "Mike")
Set

Представляет неупорядоченную коллекцию элементов, не допускающую дублирования элементов. Интерфейс MutableSet реализуется следующими типами изменяемых наборов: LinkedHashSet объединяет возможности хеш-таблицы и связанного списка, HashSet представляет хеш-таблицу.

val people: Set<String> = setOf("Tom", "Sam", "Bob", "Mike")
val people: HashSet<String> = hashSetOf("Tom", "Sam", "Bob", "Mike") // java collections
val people: LinkedHashSet<String> = linkedSetOf("Tom", "Sam", "Bob", "Mike") // java collections
MutableSet

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

val people: MutableSet<String> = mutableSetOf("Tom", "Sam", "Bob", "Mike")
Map

Не расширяет Collection и представляет набор пар ключ-значение, где каждому ключу сопоставляет некоторое значение. Все ключи в коллекции являются уникальными. Интерфейс MutableMap реализуется рядом коллекций - HashMap простейшая реализация интерфейса MutableMap, не гарантирует порядок элементов в коллекции, LinkedHashMap представляет комбинацию HashMap и связанного списка.

val people: Map<Int, String> = mapOf(1 to "Tom", 2 to "Sam", 3 to "Bob")
val people: LinkedHashMap<Int, String> = linkedMapOf(1 to "Tom", 2 to "Sam", 3 to "Bob") // java collections
val people: HashMap<Int, String> = hashMapOf(1 to "Tom", 2 to "Sam", 3 to "Bob") // java collections
MutableMap

Изменяемая коллекция Map.

val people: MutableMap<Int, String> = mutableMapOf(1 to "Tom", 2 to "Sam", 3 to "Bob")
Sequences
04.04.2022https://www.raywenderlich.com/31290959-kotlin-sequences-getting-started

Последовательности представляет собой ленивую коллекцию, которая позволяет эффективно работать с большими объемами данных или сложными цепочками преобразований. Основная особенность Sequence — это ленивое выполнение, что означает, что элементы вычисляются по мере необходимости, а не сразу.

• Вычисляет элементы только при необходимости, а не сразу при создании. Это позволяет избежать лишних вычислений и экономит ресурсы. Это особенно полезно при работе с большими данными или при выполнении сложных цепочек преобразований.

• Методы, такие как map, filter, и flatMap возвращают новый Sequence, который будет вычисляться при итерации. Преобразования применяются по цепочке, что минимизирует количество проходов по данным.

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

// Элементы фильтруются и преобразуются по мере необходимости, а не сразу.
val numbers = (1..10).asSequence()
val result = numbers
    .filter { it % 2 == 0 }
    .map { it * it }
    .toList()

println(result) // Output: [4, 16, 36, 64, 100]

Отличие от коллекций

Основное различие между Sequences и коллекциями в Kotlin заключается в способе обработки данных: ленивое вычисление в последовательностях и жадное вычисление в коллекциях. Sequence более подходит для ленивых вычислений и сложных цепочек преобразований, в то время как коллекции подходят для простых задач с быстрым доступом к данным.

Коллекции:

• Операции, такие как map, filter, и другие, выполняются сразу над всеми элементами коллекции.

• При каждом преобразовании (например, при применении нескольких последовательных функций map, filter) коллекция обрабатывается целиком на каждом шаге. Это может приводить к нескольким проходам по данным.

• Эффективны для небольших наборов данных или когда нужно быстро получить результат сразу после выполнения всех операций.

• Поддерживают произвольный доступ (например, list[2]), что делает их удобными для операций, зависящих от индексов.

// Сначала вся коллекция умножается на 2, а затем результат фильтруется, что приводит к двум проходам по данным.
val result = listOf(1, 2, 3, 4, 5)
    .map { it * 2 }
    .filter { it % 3 == 0 }
    .toList()

Последовательности:

• Выполняются лениво, что означает, что операции, такие как map или filter, откладываются до момента, когда результат действительно нужен (например, когда вызывается терминальная операция вроде toList).

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

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

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

// Каждый элемент будет умножен на 2, проверен на делимость на 3 и сохранен в результат, что минимизирует количество операций.
val result = listOf(1, 2, 3, 4, 5)
    .asSequence()
    .map { it * 2 }
    .filter { it % 3 == 0 }
    .toList()

asSequence

Преобразует коллекцию в Sequence.

val list = listOf(1, 2, 3, 4, 5)
val sequence = list.asSequence()

map

Применяет функцию преобразования к каждому элементу.

val transformedSequence = sequence.map { it * 2 }

filter

Отбирает элементы, удовлетворяющие условию.

val filteredSequence = sequence.filter { it % 2 == 0 }

generateSequence

Позволяет создавать бесконечные последовательности, которые можно ограничить с помощью методов, таких как take.

val infiniteSequence = generateSequence(1) { it + 1 }
val firstFive = infiniteSequence.take(5).toList()
println(firstFive) // Output: [1, 2, 3, 4, 5]
contentToString

Предназначен для удобного преобразования коллекций и массивов в строковое представление.

// Пример для массива
val numbers = arrayOf(1, 2, 3, 4, 5)
val stringRepresentation = numbers.contentToString()
println(stringRepresentation) // Output: [1, 2, 3, 4, 5]
Kotlin Collection. Вопросы на собесе
  1. Чем отличаются Collection и Sequences?
  1. Чем отличаются List и ArrayList?
  1. Как избежать ConcurrentModificationException?
  1. Kакие типы коллекции существуют в Kotlin?

    List MutableList Set MutableSet Map MutableMap

  1. Зачем в Kotlin коллекции делятся на mutable и immutable?

    Предотвращается изменение данных при передаче, улучшается предсказуемость и потокобезопасность в многопоточном окружении без дополнительных синхронизаций.