Массивы как тип данных
Массив можно представить как сгруппированные вместе данные одного типа. При этом заранее известно количество этих данных-элементов, а также у каждого элемента есть свое место в массиве. На рисунке ниже показан пример одного массива, элементами которого являются целые числа. Каждое число лежит в своей ячейке, а над ячейкой написан ее номер – индекс элемента.
Такая "упаковка" данных обеспечивает удобство их обработки, когда значений слишком много, чтобы присваивать каждое отдельной переменной. Проще присвоить одной переменной целую группу, а к элементам в случае необходимости обращаться по их индексу.
В языке программирования Kotlin тип данных "массив" обозначается словом Array
. Объявление переменных этого типа ничем не отличается от объявления переменных ранее нами изученных, за исключением того, что дополнительно указывается тип элементов массива. Это делается в угловых скобках после слова Array
.
Примеры объявления массивов разных типов:
fun main() { val a: Array<Int>; val b: Array<String>; val c: Array<Double>; }
Здесь массив a предназначен для хранения целых чисел, b – строк, c – вещественных чисел.
Другими словами, несмотря на то, что сам массив – Array
– это один тип данных, на самом деле это тип с вариациями, так называемый дженерик – общий. Поэтому переменной, объявленной как массив целых чисел, нельзя присвоить, например, массив строк.
Самый простой способ инициировать значением переменную типа Array
– это вызвать встроенную в Kotlin функцию arrayOf()
, которой в скобках передать через запятую элементы массива. Функция сама посчитает их количество, которое потом мы можем узнать через свойство массива size
.
fun main() { val a: Array<Double> = arrayOf(1.0, 1.3, -1.2) val s: Int = a.size var i = 0 while (i < s) { println(a[i]) i++ } }
В программе на экран выводятся значения элементов массива. К ним мы обращаемся по индексу, который указывается в квадратных скобках после имени массива. В данном случае в цикле переменная i, которой мы назначили роль индекса, принимает значения 0, 1 и 2. Когда i становится равна трем, цикл завершает свою работу, потому что выражение 3 < 3
возвращает ложь (i равна трем и s равна трем).
С помощью квадратных скобок можно не только извлекать значение из массива (на самом деле оно не извлекается, а остается там, мы просто его "берем и смотрим"), но и менять значение в ячейке, обращаясь к ней по индексу. Если после обращения к элементу массива стоит знак присвоения, значит элемент не извлекается, а перезаписывается.
fun main() { val a: Array<Double> = arrayOf(1.0, 1.3, -1.2) a[1] = 2.8 a[0] = a[2] * 2 println(a[0]) println(a[1]) println(a[2]) }
Обратите внимание, что массив объявлен как неизменяемый – через val
. Однако это не мешает нам изменять значение его элементов. На самом деле переменная действительно остается неизменяемой. Ей нельзя присвоить другой массив. Но в самом массиве менять элементы можно.
Заполним массив случайными числами:
import kotlin.random.Random fun main() { val a: Array<Int> = arrayOf(0, 0, 0, 0, 0) var i = 0 while (i < a.size) { a[i] = Random.nextInt(10) print(a[i]) print(" ") i++ } }
Если массив надо инициировать не пятью значениями, а, скажем, сотней, то записать такое количество нулей в вызове функции arrayOf()
будет проблематично.
Есть другой способ создания массива – путем вызова класса Array
. Как уже было сказано, типы данных это и есть классы данных. В Kotlin имя класса, упомянутое после знака присваивания, означает вызов конструктора этого класса. Конструктор создает объект этого типа, то есть экземпляр класса.
В конструктор класса Array
мы должны передать количество элементов массива и так называемую лямбда-функцию, посредством которой будут вычислены значения элементов массива. В простейшем случае, если мы хотим инициировать все элементы одинаковым значением, достаточно передать это значение. Однако заключать его надо в фигурные скобки, так как по сути это сокращенная до нельзя лямбда-функция.
val a: Array<Int> = Array(5, {0})
В Kotlin такой лямбда-аргумент функции принято выносить за скобку:
val a: Array<Int> = Array(5) {0}
На скрине вместо цикла while
используется цикл for
, особенности работы которого мы рассмотрим в следующем уроке.
Практическая работа:
-
Заполните массив строками, которые пользователь вводит с клавиатуры и затем выведите их на экран в обратном порядке.
-
Заполните массив случайными целыми числами. Найдите элементы с максимальным и минимальным значением, используя функции-методы массива
min()
иmax()
.
PDF-версия курса с ответами к практическим работам