Lesson 7 - Arrays in Kotlin
Lesson highlights
Are you looking for a quick reference on Kotlin arrays instead of a thorough-full lesson? Here it is:
Shortened initialization of an array:
var numbers = arrayOf(2, 3, 5, 7)
Writing 1
at the position [0]
:
numbers[0] = 1
Reading the value (now 1
) at the position
[0]
:
{KOTLIN_CONSOLE}
var numbers = arrayOf(2, 3, 5, 7)
numbers[0] = 1
println(numbers[0])
{/KOTLIN_CONSOLE}
Printing the whole array:
{KOTLIN_CONSOLE}
var numbers = arrayOf(2, 3, 5, 7)
numbers[0] = 1
for (i in numbers) {
print("$i ")
}
{/KOTLIN_CONSOLE}
Creating an empty array and generating the
values using a for
loop:
{KOTLIN_CONSOLE}
var numbers = arrayOf<Int>()
for (i in 1..10) {
numbers += i
}
for (i in numbers) {
print("$i ")
}
{/KOTLIN_CONSOLE}
Sorting/searching and more array methods and properties:
{KOTLIN_CONSOLE}
var numbers = arrayOf(2, 3, 3, 5, 7);
println("size: ${numbers.size}")
println("Min: ${numbers.min()}")
println("Max: ${numbers.max()}")
println("First: ${numbers.first()}")
println("Last: ${numbers.last()}")
println("Contains value 2: ${numbers.contains(2)}")
numbers.sort()
println("Sorted: ${numbers.contentToString()}")
println("Reversed: ${numbers.contentToString()}")
// Even more array methods can be found used in the lesson below
{/KOTLIN_CONSOLE}
Would you like to learn more? A complete lesson on this topic follows.
In the previous lesson, Type system: Null safety in Kotlin, we learned how to use nullable types. In today's lesson, we're going to introduce you all to the array data structure and show you what it's capable of accomplishing.
Array
Imagine that you want to store some information of multiple items, e.g. you
want to keep 10 numbers in the memory, each of the fields of a checkerboard or
names of 50 users. Perhaps you realize that there must be an easier way than to
start typing variables like user1
, user2
... up until
user50
. Despite the fact that there may be 1000 of them. How would
go about searching for something in there? Definitely not like that!
If we need to store a larger amount of variables of the same
type, we can solve this problem using an array. We can imagine it as a
row of boxes, each of them containing one item. The boxes are numbered by
indexes, the first one has index 0
.
(We see an array of 8 numbers in this picture)
Programming languages are very different in the way they work with arrays. In some languages (especially the older ones, compiled), it wasn't possible to create an array with a size specified at runtime (e.g. to specify its size using some variable). Arrays had to be declared with a constant size in the source code. A workaround was made by inventing pointers and custom data structures, which often lead to errors in manual memory management and to program instability (e.g. in C++). On the other hand, some interpreted languages allow us to not only declare arrays of any size but to also change the size of an existing array (it's possible e.g. in PHP). We know that Kotlin belongs to the modern ones, you don't have to think about the size of arrays (you don't even have to specify it) and you can add new items to an already existing array.
We declare an array using the arrayOf()
function:
var numbers = arrayOf<Int>()
numbers
is obviously a name of our variable.
First, let's add new items using the +=
operator. In our case,
after the operator, we'll specify a new number as Int
, which will
be stored at the end of the array:
var array = arrayOf<Int>()
array += 34
We can also add another array of the same type to an array (meaning the
Int
type, in our case) whose items will be added to the array.
We access array items through brackets with the item index specified. Of course, we can do so only when there's really an item at the given index. Let's try it:
var numbers = arrayOf<Int>() numbers += 34 print(numbers[0])
We printed the item with the index 0
, i.e. the first one, since
the item indexes are zero-based. In the output, we can see the number
34
which is stored at that index.
34
Filling the array manually like this wouldn't be too effective. Let's use a
loop and fill the array with numbers from 1
to 10
.
We'll use the for
loop to fill the array.
var numbers = arrayOf<Int>() for (i in 1..10) { numbers += i }
If we want to print this array, we need to add this piece of code after the one above:
for (i in numbers) { print("$i ") }
Now we can see the true power of the for
loop in Kotlin. All we
have to do is to pass the array after the in
keyword instead of a
numeric range and the loop will go through all the items. In the loop's body, we
can access the items and for example print them:
1 2 3 4 5 6 7 8 9 10
Arrays have the size
property, in which the number of items is
stored.
Of course, we can fill an array manually even without going through each
index to assign the values. We can use the arrayOf()
function and
list the items in the brackets, separated by commas. Now, let's try to create an
array of strings:
val simpsons = arrayOf("Homer", "Marge", "Bart", "Lisa", "Meggie")
We don't want anyone to change our array now, therefore we declare it using
val
which makes the array constant. We omit the type specification
since Kotlin easily recognizes from the items that it's a String
array. Of course, however, nothing stops us from specifying it:
val simpsons: Array<String> = arrayOf("Homer", "Marge", "Bart", "Lisa", "Meggie")
Arrays are often used to store intermediate results, which are used later in the program. When we need some result 10 times, we won't calculate the same thing 10 times, instead, we'll calculate it once and put it into the array, then we just read the result.
Array methods
Kotlin provides us with several utility methods for working with arrays. Let's look at them.
sort()
and sorted()
As the name suggests, the methods sort our array. The sort()
method sorts an already existing arrays (it must be declared using
var
) and sorted()
returns a new sorted array, so we
musn't forget to assign it to a variable. The methods are even so clever that
they work accordingly to what is stored in the array. It sorts
String
s by name and numbers by their value. Let's try to sort and
print our Simpsons family:
val simpsons: Array<String> = arrayOf("Homer", "Marge", "Bart", "Lisa", "Meggie") simpsons.sort() for (simpson in simpsons) { println(simpson) }
The output:
Bart Homer Lisa Maggie Marge
And the same thing using sorted()
:
val simpsons: Array<String> = arrayOf("Homer", "Marge", "Bart", "Lisa", "Meggie") val simpsons_sorted = simpsons.sortedArray() for (simpson in simpsons_sorted) { println(simpson) }
The output:
Bart Homer Lisa Maggie Marge
Try to create an array of numbers and verify that it actually works for them as well.
reverse()
and
reversedArray()
These methods reverse the array (the first item will be the last, and so on).
The principle is the same as with the sorting. The reversed()
method sorts an existing array, reversedArray()
returns a new
reversed array. We can use reversing e.g. for descending sorting:
val simpsons: Array<String> = arrayOf("Homer", "Marge", "Bart", "Lisa", "Meggie") simpsons.sort() simpsons.reverse() for (simpson in simpsons) { println(simpson) }
The output:
Meggie Marge Lisa Homer Bart
indexOf()
The method will find the index of the first occurrence of an element in the
array and return its index as Int
. The element may not be in the
array, the method returns -1
in this case. We'll create a simple
program that will assume that the Simpsons are sorted by popularity. When the
user enters one, we'll print on which position the Simpson is, or that the input
doesn't exist in the array.
val simpsons = arrayOf("Homer", "Marge", "Bart", "Lisa", "Meggie") println("Hi, enter your favorite Simpson (the Simpsons family): ") val simpson = readLine()!! val position = simpsonovi.indexOf(simpson) if (position != -1) { println("Yeah, that's my number ${position + 1} Simpson!") } else { println("Hey that's not Simpson!") }
The output:
Hi, enter your favorite Simpson (the Simpsons family): Homer Yeah, that's my number 1 Simpson!
size
We've already mentioned size
, it contains the number of elements
in the array. It's not a method, but a property, so we don't use brackets
()
here.
isEmpty()
As you may guess, this method will return true
if the array is
empty. Its notation is more readable than array.size == 0
. The code
clearly says we're interested in the possibility the array is empty.
min()
and max()
Math methods returning the lowest element (min()
) and the
greatest element (max()
) of the array. The result is returned as a
nullable type, in case of the array being empty.
first()
and last()
Just by looking at the names of the methods, we can guess they return the first and the last element. The returned values are nullable again.
contains()
The method returns true
/false
depending on whether
an element given through the method parameter exists in the array.
That's enough for today, you can play with arrays for a while if you'd like. In the next lesson, Solved tasks for Kotlin lesson 7, I've got a surprise for you I think you might like
In the following exercise, Solved tasks for Kotlin lesson 7, we're gonna practice our knowledge from previous lessons.