Списки
List
listOf возвращает список, доступный только для чтения, заполненный элементами, полученными из аргументов. Создает list c элементами, будет создан ArrayList (реализация ArrayList).
List и Set - это интерфейсы с методами (правилами) для реализации хранения списочных данных и множества.
mutableListOf изменяемый список, поддерживающий множество функций для добавления, удаления и обновления содержимого
Доступ к элементам списка:
val patronList = listOf("Eli", "Mordoc", "Sophie") println(patronList[0]) //вызывается метод patronlist.get(0)
Проверка содержимого:
patronList.contains("Eli") patronList.containsAll(listOf("Sophie", "Mordoc"))
Удаление и добавление элементов:
patronList.remove("Eli") patronList.add("Alex") patronList.add(0,"Alex") //добавление в начало списка patronList[0] = "Alexis" //замена значения элемента
Преобразование множества в список:
val patrons = listOf("Eli Baggins", "Eli Baggins", "Eli Ironfoot") .toSet() .toList() [Eli Baggins, Eli Ironfoot] patrons[0] Eli Baggins
Необходимость удалять дубликаты и использовать доступ по индексу очень распространена, поэтому Kotlin предоставляет функцию с именем distinct, которая внутренне вызывает toSet и toList.
val patrons = listOf("Eli Baggins", "Eli Baggins", "Eli Ironfoot").distinct() [Eli Baggins, Eli Ironfoot] patrons[0] Eli Baggins
Если нужно изменить элементы в списке, используйте MutableList. В противном случае хорошим решением будет запретить изменяемость, используя обычный список.
В Java
ArrayList
.add - можно добавлять элементы и считывать по индексу.
LinkedList - хранится двухсвязный список, представляющий собой элемент со ссылкой на предыдущий и следующий. Не особо используется, поэтому из Kotlin Collections его удалили. Но можно использовать Java библиотеку
Set - множество. Нет массива и двусвязного списка. Порядок не сохраняется
Map - список пар ключ-значение. Зная ключ можно получить значение
Map<String, String> map = new Hashmap<>() map.put("new key", "new value") firstElement = map.get("new key")
Итерация
Это повторение какого-либо действия. Итерация в математике — повторное применение какой-либо математической операции.
Списки поддерживают множество разных функций, позволяющих выполнить некоторое действие для каждого элемента списка. Эта идея называется итерацией.
Один из способов выполнить итерацию со списком — использовать цикл for. Его логика такова: «Для каждого элемента в списке сделай то-то». Вы должны определить имя элемента, а компилятор Kotlin автоматически определит его тип.
forEach
Цикл for прост и легкочитаем, но если вы предпочитаете более функциональный стиль, используйте функцию forEach.
Функция forEach обходит каждый элемент в списке — последовательно от начала до конца — и передает каждый элемент анонимной функции в аргументе.
patronList.forEach { patron -> println("Good evening, $patron") }
Если вам потребуется получить индекс каждого элемента в списке, используйте forEachIndexed
patronList.forEachIndexed { index, patron -> println("Good evening, $patron - you're #${index + 1} in line.")
Чтение из файла
val menuList = File ("data/tavern-menu-data.txt") .readText() .split("\n")
Заказ случайного напитка
placeOrder(patron, menuList.shuffled().first())
Деструктуризация
Деструктуризация позволяет объявить несколько переменных и присвоить им значения в одном выражении.
val (type, name, price) = menuData.split(',')
Если вы хотите деструктурировать только первое и третье значения из списка посетителей, это можно сделать так:
val (goldMedal, _, bronzeMedal) = patronList
Множества (Set)
Создать множество можно с помощью функции setOf.
val planets = setOf("Mercury", "Venus", "Earth")
Если попробовать добавить в множество одну и ту же планету дважды, в нем останется только одна.
val planets = setOf("Mercury", "Venus", "Earth", "Earth") ["Mercury", "Venus", "Earth"]
Множество позволяет проверить присутствие конкретного элемента с помощью contains или containsAll
planets.contains("Earth") true planets.contains("Pluto") false
Множество не индексирует свое содержимое — это означает, что оно не поддерживает встроенный оператор [] для доступа к элементам по индексу. Тем не менее можно запросить элемент по определенному индексу с помощью функции, которая использует итерации для решения своей задачи. Чтобы получить доступ к третьей планете в множестве с помощью функции elementAt
val planets = setOf("Mercury", "Venus", "Earth") planets.elementAt(2) Earth
Но имейте в виду, что доступ по индексу в множестве работает на порядок медленнее, чем доступ по индексу в списке. Это связано с внутренним устройством elementAt. Когда функция elementAt вызывается для множества, она последовательно перебирает его элементы, пока не достигнет заданного индекса. Это означает, что в большом множестве доступ к элементу с большим индексом будет происходить медленнее, чем доступ по индексу в списке. По этой причине, если вам нужен доступ по индексу, используйте список, а не множество.
Однако множества обладают очень ценным свойством устранения повторяющихся элементов. Но как быть, если программисту требуется обеспечить уникальность элементов и высокая скорость доступа по индексу? Можно использовать следующий прием: создайте множество, чтобы удалить дубликаты, а потом преобразуйте его в список, когда вам понадобится доступ по индексу или функции-мутаторы.
val uniquePatrons = mutableSetOf<String>() (0..9).forEach{ val first = patronList.shuffled().first() val last = lastName.shuffled().first() val name = "$first $last" uniquePatrons += name } println(uniquePatrons)
Цикл while
Логика цикла while следующая: «Пока условие истинно, выполнять код в блоке».
while (orderCount <= 9) { placeOrder(uniquePatrons.shuffled().first(), menuList.shuffled().first()) orderCount++ }
Оператор break
Один из способов завершить цикл while — изменить состояние, которое он проверяет. Другой способ — оператор break.
Map
val map = mapOf("key" to "value", "new key" to "new value") val value = map.get("key")
Дополнительно:
https://kiparo.com/kotlin-collections
Для собеседования