Коллекции представляют собой гибкие «контейнеры», которые позволяют хранить вместе любое количество значений. Двумя самыми популярными типами коллекций являются массивы и списки.
Содержание статьи
- Массивы в Kotlin
- Что такое массив?
- Когда лучше использовать массивы?
- Создание массивов в Kotlin
- Массивы примитивных типов IntArray, FloatArray, DoubleArray
- Массив с аргументами для функции main()
- Итерация по массиву в Kotlin
- Списки в Kotlin
- Создание списков в Kotlin
- Изменяемые списки в Kotlin
- Получение доступа к элементам списка в Kotlin
- Использование свойств и методов для списков
- Индекс элемента из списка или массива
- Срез массива или списка через метод slice()
- Проверка существования элемента в списке
- Манипуляция со списками в Kotlin
- Добавление элемента в список
- Вставка элемента в список по индексу
- Удаление элемента из списка в Kotlin
- Удаление элемента из списка по индексу
- Как получить индекс элемента из списка?
- Замена и сортировка элементов из списка
- Итерация по списку в Kotlin
- Итоговые задания для проверки
- Главные особенности списков и массивов в Kotlin
Массивы в Kotlin
Массив в Kotlin соответствует базовому типу массива в Java. Массивы являются типизированными, как обычные переменные и константы, и они могут хранить много значений.
Перед созданием первого массива давайте подробнее рассмотрим, что из себя представляет массив и зачем он используется.
Что такое массив?
Массив является упорядоченной коллекцией значений одного типа. У элементов в массиве нулевая индексация. Это означает, что индекс первого элемента равен 0, индекс второго элемента равен 1 и так далее. Зная это, вы можете определить, что индекс последнего элемента будет на 1 меньше общего числа значений в массиве.
В данном массиве пять элементов с индексами от 0 до 4.
Все его значения имеют тип String
, поэтому в массив, содержащий только строки, нельзя добавить значения другого типы кроме строк. Обратите внимание, что одно и то же значение может встречаться несколько раз.
Когда лучше использовать массивы?
Массивы пригодятся при необходимости хранить элементы в определенном порядке. Элементы можно будет отсортировать или сделать их выборку по индексу без итерации по всему массиву.
К примеру, при хранении данных о спортивных рекордах, порядок очень важен. Наивысший балл должен быть первым в списке (его индекс 0), далее идет второй лучший балл и так далее.
Создание массивов в Kotlin
Самым простым способом создания нового массива является использование функции arrayOf()
из стандартной библиотеки Kotlin. Таким образом можно быстро указать какие значения должен хранить массив.
1 2 3 | fun main() { val evenNumbers = arrayOf(2, 4, 6, 8) } |
Поскольку данный массив содержит только целые числа, Kotlin воспринимает evenNumbers
как массив значений типа Int
. Этот тип записывается как Array<Int>
. Тип внутри угловых скобок определяет тип значений, которые может хранить массив. Именно тип компилятор будет использовать при добавлении элементов в массив.
Если вы попытаетесь добавить строку в массиве в котором только числа, то компилятор вернет ошибку, и код не скомпилируется. Такой синтаксис для типа массива является примером аргумента типа или дженерики, о котором вы узнаете подробнее в следующем уроке.
Также, возможно создать массив, у которого все значения будут значениями по умолчанию:
1 2 3 | fun main() { val fiveFives = Array(5, { 5 }) // 5, 5, 5, 5, 5 } |
Подробнее о таком синтаксисе { 5 }
мы поговорим в уроке о лямбдах.
Как и с любым другим типом, лучше объявлять массивы, которые не будут меняться, то есть как константы. Рассмотрим следующий массив:
1 2 3 | fun main() { val vowels = arrayOf("a", "e", "i", "o", "u") } |
Константа vowels
является массивом из строк, значения которых изменить нельзя. Это правильно, потому что список гласных букв уже давно не менялся.
Массивы примитивных типов IntArray, FloatArray, DoubleArray
При использовании функции arrayOf()
и создании массивов с типами вроде Array<Int>
итоговый массив представляет собой список из объектов. В частности, если вы работаете в JVM, целочисленный тип будет упакован как класс Integer
, а не как примитивный тип int
. Использование примитивных типов по сравнению с их упакованными аналогами в виде классов потребляет меньше памяти и приводит к повышению производительности. К сожалению, вы не можете использовать примитивы со списками (которые рассматриваются в следующем разделе), поэтому решение, стоит ли это делать, нужно принимать для каждого отдельного случая.
Стандартная библиотека Kotlin содержит и другие функции, не только arrayOf()
, которые позволяют создавать массивы, соответствующие массивам примитивных типов. К примеру, вы можете создать массив нечетных чисел следующим образом:
1 2 3 | fun main() { val oddNumbers = intArrayOf(1, 3, 5, 7) } |
При запуске Kotlin в JVM, массив oddNumbers
компилируется в Java массив типа int[]
.
К другим функциям стандартной библиотеки относятся:
floatArrayOf()
doubleArrayOf()
booleanArrayOf()
Данные функции создают массивы типов IntArray
, FloatArray
, DoubleArray
и так далее. Вы также можете передать число в конструктор для данных типов. К примеру, для создания массива нулей.
1 2 3 | fun main() { val zeros = DoubleArray(4) // 0.0, 0.0, 0.0, 0.0 } |
Выполнить конвертацию между упакованными и примитивными массивами можно с помощью функции toIntArray()
.
1 2 3 | fun main() { val otherOddNumbers = arrayOf(1, 3, 5, 7).toIntArray() } |
Теперь типом константы otherOddNumbers
является IntArray
, а не Array<Int>
.
Массив с аргументами для функции main()
С функции main()
начинается каждая программа на Kotlin. В версии Kotlin 1.3 у функции main
появился необязательный параметр args
типа Array<String>
:
1 2 3 | fun main(args: Array<String>) { // тут пишем код... } |
При запуске программы из командной строки вы можете отправить аргументы для функции main
, как и в обычной программе которая запускается из командной строки.
Поскольку здесь мы используем IntelliJ IDEA, вы можете отправлять аргументы в функцию main
, используя конфигурацию проекта, доступ к которой осуществляется через меню Edit Configurations… на панели инструментов IntelliJ:
После этого появится окно Run/Debug Configurations. Убедитесь, что ваша конфигурация выбрана на панели слева, затем добавьте аргументы в поле Program arguments с правой части и нажмите ОК:
Итерация по массиву в Kotlin
Чтобы увидеть аргументы, переданные в функцию main
, вы можете использовать цикл for
, о котором мы рассказывали в прошлых уроках.
Однако для итерации по массиву вместо использования подсчета и интервала в цикле for
вы используете переменную вроде arg
которая будет содержать значение из массива args
в зависимости от текущей итерации по массиву:
1 2 3 4 5 | fun main(args: Array<String>) { for (arg in args) { println(arg) } } |
Результат:
1 2 3 4 5 6 7 8 | do re mi fa sol la ti do |
Значение arg
обновляется для каждой итерации по массиву. Для каждого элемента массива args
по одной итерации. Использование println(arg)
в теле цикла выводит каждый из аргументов, переданных функции main
.
Альтернативная форма итерации использует метод forEach
от массива (напоминает JavaScript):
1 2 3 4 5 | fun main(args: Array<String>) { args.forEach {arg -> println(arg) } } |
Подробнее о синтаксисе так называемого trailing lambda, используемом в вызове forEach, мы поговорим в будущих уроках про Lambda.
Списки в Kotlin
Концептуально списки очень похожи на массивы. Как и в Java, тип List в Kotlin является интерфейсом, у которого есть конкретные реализации типов вроде ArrayList
, LinkedList
и других. В плане производительности массивы обычно эффективнее списков, однако у списков есть возможность динамически менять свой размер.
У массивов фиксированный размер, а вот значения из списка можно увеличить или уменьшить в случае необходимости. Об динамических списках далее будет рассказано более подробно.
Создание списков в Kotlin
В стандартной библиотеке Kotlin есть функция для создания списка:
1 | val innerPlanets = listOf("Mercury", "Venus", "Earth", "Mars") |
Типом константы innerPlanets
является List<String>
, где String
является еще одним примером аргумента типа. Таким образом innerPlanets
можно передать в любую функцию, которой требуется список в качестве аргумента.
Под капотом innerPlanets
типом для хранения данных, является ArrayList
. Если по какой-то причине вам нужно, чтобы у innerPlanets
был тип ArrayList
, можно использовать другую функцию из стандартной библиотеки.
1 | val innerPlanetsArrayList = arrayListOf("Mercury", "Venus", "Earth", "Mars") |
После их создания — списки innerPlanets
и innerPlanetsArrayList
изменить нельзя. Для этого требуется создать изменяемый список.
Пустой список можно создать без передачи аргументов в list()
. Поскольку сейчас компилятор не может определить тип, вам нужно использовать объявление типа:
1 | val subscribers: List<String> = listOf() |
Вы также можете поместить аргумент типа в функцию:
1 | val subscribers = listOf<String>() |
Так как список, возвращаемый из listOf()
, является неизменяемым, вы не сможете что-то сделать с данным пустым списком. Пустые списки полезны как стартовая точка для изменяемых списков.
Ни один из списков innerPlanets
, innerPlanetsArrayList
или subscribers
не может быть изменен после создания. Для этого нужно создать изменяемый список.
Изменяемые списки в Kotlin
В стандартной библиотеке Kotlin есть функция и для изменяемых списков:
1 | val outerPlanets = mutableListOf("Jupiter", "Saturn", "Uranus", "Neptune") |
Мы создали в константе outerPlanets
изменяемый список, просто на тот случай, если в нашей Солнечной системе внезапно будет открыта новая планета. Вы можете создать пустой изменяемый список, не передавая никаких аргументов в функцию:
1 | val exoPlanets = mutableListOf<String>() |
Позже будет показано, как добавить или удалить элементы из изменяемого списка.
Получение доступа к элементам списка в Kotlin
От возможности создавать массивы и списки мало толку, если вы не знаете, как извлекать из них значения. Далее мы рассмотрим несколько различных способов доступа к элементам. Синтаксис одинаков как для массивов, так и для списков.
Использование свойств и методов для списков
Представьте, что вы создаете карточную игру. Вам нужно сохранить имена игроков в списке. Список должен меняться по мере того, как игроки заходят или выходят из игры, поэтому требуется объявить изменяемый список:
1 2 3 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan") } |
В данном примере, константа players
является изменяемым списком, потому что вы использовали функцию mutableListOf()
из стандартной библиотеки.
Перед началом игры необходимо убедиться, что игроков достаточно. Можно использовать метод isEmpty()
, чтобы проверить если список не является пустым:
1 2 3 4 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan") print(players.isEmpty()) // Результат: false } |
Список не пустой, но для начала игры нужно хотя бы два игрока. Получить число игроков можно через использование свойства size
от списка:
1 2 3 4 5 6 7 8 9 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan") if (players.size < 2) { println("Нам нужно хотя бы два игрока!") } else { println("Начнем!") } } |
На заметку: В будущих уроках вы узнаете больше о свойствах и методах. Пока просто думайте о свойствах как о переменных, которые встроены в значения. Чтобы получить доступ к свойству, поставьте точку после имени константы или переменной, которая хранит значение, и за ней следует имя свойства, к которому вы хотите получить доступ. Аналогично, думайте о методах как о функциях которые встроены в значения.
Время начать игру! Вы решили, что порядок в игре определяется порядком имен в списке. Как бы вы узнали имя первого игрока из списка?
Списки предоставляют метод first()
для получения первого объекта из списка:
1 | var currentPlayer = players.first() |
Вывод значения из currentPlayer
поднимает интересный вопрос:
1 2 3 4 5 6 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan") var currentPlayer = players.first() println(currentPlayer) // Результат: Alice } |
Каким был бы вывод, если бы список players
оказался пустым?
В таком случае появилась бы ошибка, так что будьте осторожны при использовании свойств и методов в отношении списков.
Аналогично, у списков есть метод last()
, который возвращает последнее значение списка или выдает ошибку если список пуст:
1 2 3 4 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan") println(players.last()) // Результат: Dan } |
Другим способом получить значения из списка является вызов метода minOrNull()
. Данный метод возвращает элемент списка с наименьшим значением — не тот, у которого самый маленький индекс!
Если массив содержит строки, тогда будет использоваться алфавитный порядок, в данном случае метод minOrNull()
выведет значение "Alice"
:
1 2 3 4 5 6 7 8 9 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan") val minPlayer = players.minOrNull() minPlayer.let { println("$minPlayer начинает первым!") // Результат: Alice начинает первым! } } |
Вместо возникновения ошибки при невозможности определить минимальное значение, метод minOrNull()
вернет тип null, поэтому вам нужно проверить, является ли возвращаемое значение null.
Конечно, методы first()
и minOrNull()
не будут всегда возвращать одинаковое значение. К примеру:
1 2 3 4 5 | println(arrayOf(2, 3, 1).first()) // Вернет: 2 println(arrayOf(2, 3, 1).minOrNull()) // Вернет: 1 |
Как вы могли догадаться, у списков также есть метод maxOrNull()
.
1 2 3 4 5 6 7 8 9 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan") val maxPlayer = players.maxOrNull() if (maxPlayer != null) { println("$maxPlayer имеет наибольшее значение!") // Результат: Dan имеет наибольшее значение! } } |
На заметку: Свойство
size
а также методыfirst()
,last()
,minOrNull()
иmaxOrNull()
не являются эксклюзивными только для массивов или списков. У каждого типа коллекции есть такие свойства и методы в дополнение к множеству других. Вы узнаете больше об этом в уроке об интерфейсах.
Рассмотренные до сих пор методы полезны, если вы хотите получить первый, последний, минимальный или максимальный элемент из списка или массива. Но что, если нужный вам элемент не может быть получен одним из этих методов?
Индекс элемента из списка или массива
Наиболее удобным способом доступа к элементам массива или списка является использование синтаксис индексирования. Этот синтаксис позволяет получить прямой доступ к любому значению, используя его индекс внутри квадратных скобок:
1 2 3 4 5 6 7 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan") val firstPlayer = players[0] println("Первый игрок это $firstPlayer") // Результат: Первый игрок это Alice } |
Поскольку массивы и списки имеют нулевую индексацию, вы используете индекс 0
для получения значения первого объекта из списка.
Синтаксис индексации эквивалентен вызову метода get()
для массива или списка и передачи индекса в качестве аргумента.
1 | val secondPlayer = players.get(1) |
Вы можете использовать индексы 1, 2, 3
для получения значений следующих элементов массива или списка, но если вы попытаетесь получить значение индекса который находится за пределами размера массива или списка, вы получите ошибку и программа прекратит свою работу:
1 | val player = players[4] // Результат: ошибка IndexOutOfBoundsException |
Такая ошибка возникла, потому что список players
содержит только четыре строки. Индекс 4 запрашивает значение пятого элемента из списка, но в списке нет пятого элемента вообще.
Срез массива или списка в Kotlin
Можно использовать метод slice()
с интервалами для получения среза элементов из массива или списка.
К примеру, вот код если вам нужно получить срез имен следующих двух игроков (игнорируя первого):
1 2 3 4 5 6 7 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan") val upcomingPlayersSlice = players.slice(1..2) println(upcomingPlayersSlice.joinToString()) // Вывод: Bob, Cindy } |
Используемым интервалом является 1..2
. Он указывает на второй и третий элемент массива. Здесь можно использовать индекс, если начальное значение меньше или равно конечному значению, и оба находятся в границах массива. Если начальное значение больше конечного значения, содержимое среза будет пустым.
Объект, возвращаемый методом slice()
, представляет собой независимый от оригинала массив или список, поэтому внесение изменений в срез не влияет на исходный массив или список.
Проверка существования элемента в списке
Вы можете выполнить данную проверку с помощью оператора in
который возвращает true
, если элемент найден в списке, и false
если такого значения в списке нет.
Можно использовать эту стратегию для создания функции, которая проверяет, участвует ли определенный игрок в игре или нет:
1 2 3 4 5 6 7 8 9 | fun isEliminated(player: String, players: MutableList<String>): Boolean { return player !in players } fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan") println(isEliminated("Bob", players)) // Результат: false } |
Оператор !
используется, чтобы инвертировать результат из проверки оператором in
, т.е. из true
превращает в false
и обратно из false
в true
.
Функция спрашивает «Игрок исключен (isEliminated)?» затем проверяется если такой игрок находится в списке, если он есть в списке игроков тогда функция возвращает false
так как он не исключен из игры.
Оператор in
является эквивалентом методу contains()
. Вы можете проверить наличие элемента в определенном срезе, используя вместе методы slice()
и contains()
:
1 2 3 4 5 6 7 8 9 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan") if (players.slice(1..3).contains("Alice")) { println("Игрок найден в срезе!") } else { println("В текущем срезе такого игрока нет...") } } |
Теперь, когда вы можете получить данные из массивов и списков, пришло время взглянуть на изменяемые списки и то, как изменить их значения.
Манипуляция со списками в Kotlin
В Kotlin списки можно изменять путем добавления и удаления элементов или обновлять существующие значения, а также менять порядок элементов. В этом разделе вы увидите, как работать со списком, чтобы он соответствовал тому, что происходит в вашей игре.
Добавление элемента в список
Для участия в игре — новые пользователи должны зарегистрироваться и добавить свои имена в список. Пользователь Eli является первым игроком, который присоединиться к уже существующим участникам.
Вы можете добавить Eli в конец списка через использование метода add()
:
1 2 3 4 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan") players.add("Eli") } |
При попытке добавить что-либо, кроме строки, компилятор выдаст ошибку. Помните, что списки могут хранить только значения одного типа. Кроме того, метод add()
работает только с изменяемыми списками.
Следующим игроком, который присоединится к игре, станет Gina. Вы можете добавить её в игру другим способом, используя оператор +=
:
1 2 3 4 5 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan") players.add("Eli") players += "Gina" } |
Правая часть выражения состоит из одного элемента — строки "Gina"
. Через использование оператора +=
вы добавляете элемент в конец списка players
. Теперь список выглядит следующим образом:
1 2 3 4 5 6 7 8 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan") players.add("Eli") players += "Gina" println(players.joinToString()) // Результат: "Alice", "Bob", "Cindy", "Dan", "Eli", "Gina" } |
Последнего игрока мы добавили с помощью оператора +=
также можно добавить много других участников после Gina.
Хотя у массивов фиксированный размер, на самом деле можно использовать оператор +=
с массивом, объявленным как переменная.
1 2 3 4 5 6 | fun main() { var array = arrayOf(1, 2, 3) array += 4 println(array.joinToString()) // Результат: 1, 2, 3, 4 } |
Обратите внимание, что на самом деле вы не добавляете значение в существующий массив, а вместо этого создаете новый массив, у которого есть дополнительный элемент, и назначаете новый массив изначальной переменной.
Вставка элемента в список по индексу
Правило нашей карточной игры состоит в том, что имена игроков должны быть в алфавитном порядке. В списке нет игрока, имя которого начинается с буквы F
. К счастью, Frank только что прибыл. Его нужно добавить между Eli и Gina. Для этого можно воспользоваться опять методом add()
, но при этом указать индекс в качестве первого аргумента:
1 2 3 4 5 6 7 8 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan", "Eli", "Gina") players.add(5, "Frank") println(players.joinToString()) // Результат: Alice, Bob, Cindy, Dan, Eli, Frank, Gina } |
Первый аргумент определяет, куда добавляется элемент. Помните, что у списка нулевая индексация, поэтому индекс 5
— это индекс игрока Gina, заставляющий ее переместиться дальше, после того как её место занимает Frank.
Удаление элемента из списка в Kotlin
Внезапно выяснилось, что участники Cindy и Gina читеры. Их нужно убрать из игры! Удалить элемент из списка можно с помощью метода remove()
:
1 2 3 4 5 6 7 8 9 10 11 12 13 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan", "Eli", "Frank", "Gina") val removePlayer = "Gina" val wasPlayerRemoved = players.remove(removePlayer) if (wasPlayerRemoved) { println("Игрок $removePlayer был удален из игры!") println("Текущий список игроков: " + players.joinToString()) } else { println("Никто не был удален...") } } |
Результат:
1 2 | Игрок Gina был удален из игры! Текущий список игроков:Alice, Bob, Cindy, Dan, Eli, Frank |
Этот метод делает две вещи: удаляет элемент и затем возвращает булево значение, указывающее, что удаление прошло успешно. Таким образом вы будете уверены, что читер и правда удален из игры.
Удаление элемента из списка по индексу
Для удаления Cindy из игры нужно знать индекс, под которым хранится её имя. Взглянув на список игроков, вы увидите, что она третья в списке. Значит, её индекс под номером 2
. Для удаления Cindy используем метод removeAt()
.
1 2 3 4 5 6 7 | fun main() { val players = mutableListOf("Alice", "Bob", "Cindy", "Dan", "Eli", "Frank") val removedPlayer = players.removeAt(2) println("$removedPlayer удалили.") // > Cindy удалили println("Текущий список игроков: " + players.joinToString()) } |
Результат:
1 2 | Cindy удалили. Текущий список игроков: Alice, Bob, Dan, Eli, Frank |
В отличие от метода remove()
который возвращает только true
или false
, метод removeAt()
возвращает значение элемента, который был удален из списка. Теперь можно добавить этот элемент в список читеров!
Как получить индекс элемента из списка?
Но как получить индекс элемента, если вы его не знаете? Для этого существует метод indexOf()
, который возвращает первый индекс совпадающего элемента, потому что список может содержать несколько повторов одного и того же значения. Если метод не находит элемент, он возвращает -1
.
1 2 3 4 5 6 7 | fun main() { val players = mutableListOf("Alice", "Bob", "Dan", "Eli", "Frank") val playerIndex = players.indexOf("Eli") println("Индекс игрока: $playerIndex") // Результат: Индекс игрока: 3 } |
Задание для проверки №1
Используйте метод indexOf()
для определения позиции элемента "Dan"
в списке players
.
Замена и сортировка элементов из списка
Frank теперь хочет, чтобы все называли его Franklin. Вы могли бы удалить значение "Frank"
из списка и затем добавить "Franklin"
, но для такого простого задания все можно сделать гораздо быстрее и проще. Для обновления элемента из списка воспользуемся синтаксисом индексации.
1 2 3 4 5 6 7 8 9 10 11 | fun main() { val players = mutableListOf("Alice", "Bob", "Dan", "Eli", "Frank") println("Текущий список игроков: " + players.joinToString()) // Узнаем индекс Франклина. val frankIndex = players.indexOf("Frank") players[frankIndex] = "Franklin" println("Новый список: " + players.joinToString()) } |
Результат:
1 2 | Текущий список игроков: Alice, Bob, Dan, Eli, Frank Новый список: Alice, Bob, Dan, Eli, Franklin |
На протяжении игры некоторые участники проигрывают, и на их место приходят новые. Вы можете использовать индексирование для замены старых игроков новыми:
1 2 3 4 5 6 7 8 9 10 11 | fun main() { val players = mutableListOf("Alice", "Bob", "Dan", "Eli", "Franklin") println("Текущий список игроков: " + players.joinToString()) // Заменяем строго игрока новым игроков. players[3] = "Anna" // Сортируем список. players.sort() println("Новый список: " + players.joinToString()) } |
Результат:
1 2 | Текущий список игроков: Alice, Bob, Dan, Eli, Franklin Новый список: Alice, Anna, Bob, Dan, Franklin |
Данный код заменяет игрока Eli на игрока Alice. Затем для сортировки списка в алфавитном порядке вызывается метод sort()
.
Можно заменять содержимое из элемента путем вызова метода set()
для списка.
1 | players.set(3, "Anna") |
Вместо:
1 | players[3] = "Anna" |
Согласно IntelliJ IDEА, для таких задач — использование синтаксиса индексации обычно предпочтительнее, чем использование методов get()
и set()
.
Обратите внимание, что хотя массивы имеют фиксированный размер и не могут быть изменены, вы можете обновлять элементы массива, используя синтаксис индексации.
1 2 3 4 5 | fun main() { val arrayOfInts = arrayOf(1, 2, 3) arrayOfInts[0] = 4 println(arrayOfInts.joinToString()) // Результат: 4, 2, 3 } |
Итерация по списку в Kotlin
Время позднее, поэтому игроки решили остановиться и продолжить сражение завтра. В это время вы должны сохранить их результаты в отдельном списке. Лучшим вариантом было бы использование карт, про которых мы узнаем позже, а пока что мы используем списки:
1 | val scores = listOf(2, 2, 8, 6, 1) |
Перед тем, как игроки уйдут, вы решаете вывести имена тех, кто на данный момент все еще в игре. Как и в случае с массивами, можно использовать цикл for, о котором мы говорили в одной из предыдущих статей.
1 2 3 4 5 6 7 | fun main() { val players = mutableListOf("Alice", "Anna", "Bob", "Dan", "Franklin") for (player in players) { println(player) } } |
Результат:
1 2 3 4 5 | Alice Anna Bob Dan Franklin |
Данный код просматривает все элементы из списка players
, от индекса 0
до players.size - 1
, и выводит их значения. В момент первой итерации, переменная player
равна первому элементу из списка, во второй итерации она равна второму элементу списка и так далее, пока цикл не выведет все элементы из списка.
Если вам нужен индекс каждого элемента, то можно выполнить итерацию по возвращаемому результату из метода withIndex()
:
1 2 3 4 5 6 7 | fun main() { val players = mutableListOf("Alice", "Anna", "Bob", "Dan", "Franklin") for ((index, player) in players.withIndex()) { println("${index + 1}. $player") } } |
Результат:
1 2 3 4 5 | 1. Alice 2. Anna 3. Bob 4. Dan 5. Franklin |
Теперь можно использовать изученную технику для создания функции, которая принимает список целых чисел в качестве входных данных и возвращает сумму из этих элементов.
Данную функцию можно использовать для вычисления суммы очков игроков:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | fun sumOfElements(list: List<Int>): Int { var sum = 0 for (number in list) { sum += number } return sum } fun main() { val players = mutableListOf("Alice", "Anna", "Bob", "Dan", "Franklin") val scores = listOf(2, 2, 8, 6, 1) println("Всего очков: " + sumOfElements(scores)) } |
Результат:
1 | Всего очков: 19 |
Задание для проверки №2
Напишите программу при помощи цикла for которая вывела бы на экран имя игрока и количество его очков.
Итоговые задания для проверки
Выполните следующие задания для проверки своих знаний по работе с массивов и списков в Kotlin.
1. Какие из следующих утверждений являются верными?
1 2 3 | 1. val array1 = Array<Int>() 2. val array2 = arrayOf() 3. val array3: Array<String> = arrayOf() |
Для следующих трех случаев array4
был объявлен следующим образом:
1 | val array4 = arrayOf(1, 2, 3) |
1 2 3 | 4. println(array4[0]) 5. println(array4[5]) 6. array4[0] = 4 |
Для финальных пяти вариантов array5
был объявлен следующим образом:
1 | val array5 = arrayOf(1, 2, 3) |
1 2 3 4 | 7. array5[0] = array5[1] 8. array5[0] = "Six" 9. array5 += 6 10. for item in array5 { println(item) } |
2. Напишите функцию, которая удаляет первое число из списка целых чисел. Начало функции должна выглядеть следующим образом:
1 | fun removeOne(item: Int, list: List<Int>): List<Int> |
3. Напишите функцию, которая удаляет все совпадения какого-то целого числа из списка целых чисел. Это сигнатура функции:
1 | fun remove(item: Int, list: List<Int>): List<Int> |
4. У массивов и списков есть метод reverse()
, который разворачивает в обратном порядке значения из списка или массива. Напишите функцию, которая делает то же самое без использования метода reverse()
и возвращает новый массив с теми же элементами, но только в обратном порядке. Это сигнатура функции:
1 | fun reverse(array: Array<Int>): Array<Int> |
5. Функция ниже возвращает случайное число между from
(от — включая его) и to
(до — исключая это значение в финальном результате):
1 2 3 4 5 6 | import java.util.Random val random = Random() fun rand(from: Int, to: Int) : Int { return random.nextInt(to - from) + from } |
Используйте это для написания функции, которая перемешивает элементы массива в случайном порядке. Это сигнатура функции:
1 | fun randomized(array: Array<Int>): Array<Int> |
6. Напишите функцию, которая подсчитывает минимальное и максимальное значение из массива целых чисел. Подсчитайте эти значения сами. Не используйте методы minOrNull
и maxOrNull
. Если массив пуст, то возвращаемым результатом должен быть null
.
Сигнатура данной функции.
1 | fun minMax(numbers: Array<Int>): Pair<Int, Int>? |
Подсказка: Внутри функции можно использовать константы Int.MIN_VALUE
и Int.MAX_VALUE
.
Главные особенности списков и массивов в Kotlin
- Массивы являются упорядоченными наборами значений одного типа;
- Существуют специальные классы вроде
IntArray
, которые создаются как массивы примитивных типов в Java; - Списки похожи на массивы, но имеют дополнительную возможность динамического изменения размера;
- Вы можете добавлять, удалять, обновлять и вставлять элементы в изменяемые списки;
- Используйте индексацию или имеющийся методы для доступа к элементам и их обновления;
- Остерегайтесь доступа к индексу, который находится за пределами допустимого диапазона списка или массива;
- Можно перебирать элементы массива или списка, используя цикл for или метод
forEach
; - Можно проверить наличие элементов в массиве или в списке, используя оператор
in
;
Что дальше?
После изучения массивов и списков в Kotlin мы можем приступить к изучению двух других популярных типов коллекций — карт и множеств.
можно узнать логику, почему в ЗАДАНИИ 6 переменные:
var min = Int.MAX_VALUE
var max = Int.MIN_VALUE ?
Я так понимаю решение верное и это не обсуждается, но хотелось бы пару слов о том почему именно так.
Отличная статья спасибо
… [Trackback]
[…] Read More here: kotlins.org/arrays-lists/trackback/ […]