This is a premium alert message you can set from Layout! Get Now!

Kotlin IntArray, Array, and emptyList()

0

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 a subtype of 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[].

Type vs. class

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.

Performance

IntArray behaves better than Array in performance-critical situations. According to ”Item 55” of Kotlin Academy’s Effective Kotlin, the latter allocates five times more bytes than the former. Specifically, to store a 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 a million integers is 25% faster with IntArray.

Initialization

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.

Creation

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)

Conversion

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:

  • Class vs. list: 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
  • Sizing: MutableList is resizable, whereas Array and List are not
  • Mutability: Array is mutable, whereas List is not. If we want to modify the elements of a list, we must use MutableList
  • Invariance vs. covariance: 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
  • Types: Both Array and MutableList are optimized array types for primitive types

We 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()

Using arrays in Kotlin

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.

Getting and setting elements

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

Traversing an array

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

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; that is, 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), that is the second and third elements, were reversed.

Conclusion

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.

The post Kotlin <code>IntArray</code>, <code>Array</code>, and <code>emptyList()</code> appeared first on LogRocket Blog.



from LogRocket Blog https://ift.tt/HPQNblD
Gain $200 in a week
via Read more

Post a Comment

0 Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.
Post a Comment

Search This Blog

To Top