Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Arrays

Arrays are useful when you need an ordered sequence of values, indexed by their position in that sequence, and the length of that sequence doesn’t need to change after creation.

Creation

You can create an array in two different ways. The first approach requires you to specify the type of element to be stored in the array, the size of the array, and some code to initialize the array elements:

val numbers = Array<Float>(100) { 0.0f }

val greetings = Array<String>(5) { "Hello" }

Here, numbers is created as an array of 100 Float values, each equal to 0.0, and greetings is created as an array of 5 strings, all "Hello".

{ 0.0f } and { "Hello" } are examples of lambda expressions that specify how to compute an element’s initial value. In these two simple cases a constant value is used, but it is possible to have more complex expressions that give the elements different values. For example, you could use the lambda expression { Random.nextFloat() } to initialize the array numbers with pseudo-random values. (Try this out!)

The second approach involves specifying the desired initial values for each array element individually, passing them all to the arrayOf() function:

val numbers = arrayOf(9, 3, 6, 2)

val names = arrayOf("Nine", "Three", "Six", "Two")

With this approach, there is no longer a need to specify element type or array size: type inference is used to determine the former, and arguments are simply counted to determine the latter.

Primitive Arrays

  1. Create a file named Array.kt, in the tasks/task7_2 subdirectory of your repository. Add the following code to it:

    fun main() {
        val numbers = arrayOf(9, 6, 3, 2)
    
        val cls = numbers::class
    
        println(cls.qualifiedName)
        println(cls.java)
    }
    
  2. Compile and run the program. What does it print?

  3. Modify the first line in main() so that the intArrayOf() function is called, instead of the arrayOf() function. Recompile the program and run it again. What has changed?

The change in the first line of program output tells us arrayOf() and intArrayOf() create two different array types, but why is that? And what does that strange-looking second line of output actually mean?

On the JVM, Kotlin uses Java as much as possible to provide the underlying implementation of its classes. The second line of program output shows that underlying Java representation, in a rather cryptic form1. The opening [ indicates that a Java array is being used. The rest of the string indicates the type of value in the array. Ljava.lang.Integer; means that Integer objects are stored in the array, whereas I indicates that the array holds primitive int values.

This matters because an array of int values is handled more efficiently than an array of Integer objects (e.g., the overhead associated with boxing and unboxing operations is avoided).

This is why Kotlin has an IntArray class and an intArrayOf() function: to give us access to this more efficient representation from our Kotlin programs.

Tip

When you need an array of ‘primitives’ (numbers, characters or booleans), it is more efficient to use the dedicated classes that Kotlin provides for these types, rather than the generic Array class.

In other words, you should use IntArray, FloatArray or CharArray rather than Array<Int>, Array<Float> or Array<Char>.

Similarly, if you are creating arrays of primitives from a known set of values, you should prefer functions like intArrayOf(), floatArrayOf(), charArrayOf() to the general-purpose arrayOf() function.

Element Access

The normal way of accessing an array element is to use [], with a zero-based integer index—just as you would in C. Thus you could use x[0] to look up or modify the first element of array x.

Alternatively, you can use the get() method to retrieve an element, and the set() method to modify an element. These expect a zero-based array index, just like []. The set() method also requires the new value for the array element as a second argument.

Last year, you will have seen that C doesn’t stop you moving beyond the bounds of an array, whereas Python will prevent you from doing that with a list. Kotlin follows the same approach as Python, generating an ArrayIndexOutOfBoundsException if an invalid array index is used.

You can use slice() to return part of the array. The desired portion is specified using an integer range. Note however that the result of slicing is returned as a list, not an array.


  1. These are type descriptors, used in Java bytecode. They are written in a form that suits the JVM rather than a human reader.