IntArray
, Array
, and emptyList()
Kotlin is a very powerful statically typed programming language allowing us to write very expressive yet concise code. As is common with modern languages, such expressiveness often means we can implement the same feature in several ways. A typical example is choosing a suitable collection class for our needs.
As a matter of fact, the Kotlin library comes with a variety of different collections, that is, types grouping a number (possibly zero) of collection items.
In this article, we’ll examine arrays and integers in Kotlin. We’ll analyze two different types representing an array of integers, IntArray
and Array
. Finally, we’ll compare IntArray
and Array with
lists, a different collection type.
Jump ahead:
IntArray
vs. Array
Koltin has two different array implementations.
The first is the Array
class, generic over the type T
, representing an array of elements of type T
. Array
defines several methods allowing us to read/write an element at a given index, query the size, and so on. These array implementations are invariant. Hence, Array
is not considered a sub-type of Array
if T
is of subtype U
.
For primitive types, Kotlin also provides us with dedicated arrays, such as IntArray
or ShortArray
. There’s no subtyping between these “primitive” arrays and their generic counterpart, i.e., Array
. Nonetheless, they come with the same methods.
The main difference between an IntArray
and an Array
is that the former is represented, under the hood, as an int[]
, whereas the latter gets compiled into an Integer[]
.
The actual difference between IntArray
and an Array
in Kotlin is basically the same as the difference between int
and Integer
in Java. The former is a primitive type, not a class, storing an actual binary value representing a given integer. The latter is a Java class, defining a field of type int
.
Being a class, Integer
is more expressive, as we can invoke methods on it. Nonetheless, int
comes with better performance, as using Integer
adds overhead for even the simplest calculation.
IntArray
behaves better than Array
in performance-critical situations. According to ”Item 55” of Kotlin Academy’s book Effective Kotlin, the latter allocates five times more bytes than the former. Specifically, to store 1 million numbers, IntArray
requires 4,000,016 bytes, whereas Array
allocates 20,000,040 bytes.
Processing a primitive array is also faster. Again, according to “Item 55” of Effective Kotlin, calculating the average of 1 million integers is 25 percent faster with IntArray
.
Another difference between IntArray
and. Array
is that primitive arrays can be left uninitialized. More specifically, the elements of the array will be set, by default, to 0
:
val intArr = IntArray(5) println(intArr.joinToString(" "))
The example above will print 0 0 0 0 0
.
On the other hand, we do not have this convenience initialization for Array
. As a matter of fact, its constructor inputs two arguments, one for the size and one for a valid, non-null default value:
val arrInt = Array<Int>(5) { 1 } println(arrInt.joinToString(" "))
The above example will print 1 1 1 1 1
.
We can also use null
values, but the type of the resulting array will be different — and we’ll have to watch out for nulls
:
val arrInt = arrayOfNulls<Int>(5) // Array<Int?> println(arrInt.joinToString(" "))
The above snippet will print null null null null null
, but the type of the array is now Array<Int?>
rather than Array
.
Kotlin also provides us with factory functions to create both types of arrays:
val intArray: IntArray = intArrayOf(0, 1, 2, 3) val arrayInt: Array<Int> = arrayOf<Int>(0, 1, 2, 3)
We can turn an IntArray
into an Array
, and vice versa, using IntArray::toTypedArray()
and Array::toIntArray()
, respectively:
val arrayInt: Array<Int> = intArrayOf(0, 1, 2, 3).toTypedArray() val intArray: IntArray = arrayOf<Int>(0, 1, 2, 3).toIntArray()
As a final note, the size of both IntArray
and Array
is fixed. Once we set the number of elements, we cannot add or remove items from the arrays.
emptyList()
In addition to arrays, Kotlin provides us with other types of collections. One example is List
. There are several differences between lists and arrays in Kotlin. Here are the main differences:
Array
is a class, whereas List
and MutableList
are interfaces with different implementations. Arrays are sequential fixed-size memory regions, compiled into JVM arrays. However, for lists, it entirely depends on the actual implementation. For instance, ArrayList
makes use of an array under the hood, and hence its runtime performance is similar to that of Array
MutableList
is resizable, whereas Array
and List
are not Array
is mutable, whereas List
is not. If we want to modify the elements of a list, we must use MutableList
Array
and MutableList are
invariant on T
, whereas List
is covariant. This means that List
is a subtype of List
if T
is a subtype of U
Array
and MutableList
are optimized array types for primitive typesWe can initialize an empty list using the emptyList()
method and then turn it into an instance of Array
with List::toTypedArray()
, as we did for IntArray
:
val list: List<Int> = emptyList() val array: Array<Int> = list.toTypedArray()
Let’s take a look at the main functions to see how they work on arrays in Kotlin. In the examples that follow, the presented methods apply to both IntArray
and Array
.
The most common operations when working with arrays are surely getting and setting elements. We can do this with the get
and set
methods. Such methods are so commonly invoked that Kotlin defines syntactic sugar for them:
val array = intArrayOf(1, 12, 856, 0, -10) println(array[2]) // same as array.get(2) array[2] = 78 // same as array.set(2, 78) println(array[2])
The example above will print 856
and then 78
, confirming the array was modified in place.
However, if the array is not defined at a given index, Kotlin will throw an IndexOutOfBoundsException
:
val array = intArrayOf(1, 12, 856, 0, -10) println(array[7])
The example above will fail with the following exception:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 7 out of bounds for length 5
We can move through an array in Kotlin using a for
loop or a while
loop. These approaches, however, are a bit low level. Alternatively, Kotlin provides us with the common forEach
function, which is much more declarative than a loop:
val array = intArrayOf(1, 12, 856, 0, -10) array.forEach{ println(it) }
The example above will print all the elements of our array, one for each line.
Sometimes it may be useful to let Kotlin assign indexes to the array’s elements while iterating through the array. We can do that with forEachIndexed
:
val array = intArrayOf(1, 12, 856, 0, -10) array.forEachIndexed{ index, elem -> println("Element at index $index: $elem") }
The example above will print the following output:
Element at index 0: 1 Element at index 1: 12 Element at index 2: 856 Element at index 3: 0 Element at index 4: -10
We can traverse an array using fold
as well. We usually do that when we want to compute a value out of our array. We might use it, for example, to sum all the elements of an array:
val array = intArrayOf(1, 12, 856, 0, -10) val sum = array.fold(0, { acc, elem -> acc + elem }) println(sum)
When using fold
, the first parameter is the initial value of our computation, 0
in the example above. The second argument is a binary function used to update the partial result with each element of the array. The first parameter of such a function is the so-called accumulator, whereas the second is an element of the array. The example above will print 859
, as expected.
Sorting and reversing an array are in-place operations. This means that they won’t return a new array, but instead mutate the existing one.
To sort an array, we can invoke its sort
method:
val array = arrayOf(1, 12, 856, 0, -10) array.sort() println(array.joinToString(" "))
The example above will print -10 0 1 12 856
, showing that the array was modified. As a matter of fact, the sort
methods return Unit
.
Similarly, to reverse an array we can use reverse
:
val array = arrayOf(1, 12, 856, 0, -10) array.reverse() println(array.joinToString(" "))
The example above will print -10 0 856 12 1
, showing that the array was reversed in place. The reversal can also be partial — i.e., we can specify a start and an end:
val array = arrayOf(1, 12, 856, 0, -10) array.reverse(1, 3) println(array.joinToString(" "))
In this case, the example will print 1 856 12 0 -10
, where the elements of the indexes 1
(inclusive) to 3
(exclusive), i.e., the second and third elements, were reversed.
In this article, we investigated the difference between IntArray
and Array
, comparing different ways of creating instances of each type. We discussed different use cases for both types of arrays, compared them to lists, and saw how to turn a list into an array.
Lastly, we explored some of the most common operations on arrays, in particular how to set or get elements and how to traverse, sort, and reverse an array.
LogRocket is an Android monitoring solution that helps you reproduce issues instantly, prioritize bugs, and understand performance in your Android apps.
LogRocket also helps you increase conversion rates and product usage by showing you exactly how users are interacting with your app. LogRocket's product analytics features surface the reasons why users don't complete a particular flow or don't adopt a new feature.
Start proactively monitoring your Android apps — try LogRocket for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowExplore use cases for using npm vs. npx such as long-term dependency management or temporary tasks and running packages on the fly.
Validating and auditing AI-generated code reduces code errors and ensures that code is compliant.
Build a real-time image background remover in Vue using Transformers.js and WebGPU for client-side processing with privacy and efficiency.
Optimize search parameter handling in React and Next.js with nuqs for SEO-friendly, shareable URLs and a better user experience.