Arrays

Arrays and Specialized Arrays in Kotlin

Arrays

1. Introduction

Arrays are one of the most fundamental data structures in programming, allowing
you to store and manipulate collections of elements. Kotlin provides a powerful
and concise implementation of arrays, blending traditional array concepts with
modern language features. Whether you’re working with fixed-size collections or
need specialized types for performance, Kotlin’s array support has you covered.

In this post, we’ll explore Kotlin arrays and their specialized variants,
examining their features, syntax, and best practices for effective usage.


2. Overview of Arrays

An array in Kotlin looks like this:

val array = arrayOf(10, 20, 30, 40, 50)
println(array[0]) // Accesses 10
println(array[3]) // Accesses 40

which can be visualized as:

+-----+-----+-----+-----+-----+
|  0  |  1  |  2  |  3  |  4  |  <- Index
+-----+-----+-----+-----+-----+
| 10  | 20  | 30  | 40  | 50  |  <- Values
+-----+-----+-----+-----+-----+

Definition and Purpose

An array in Kotlin is a collection of elements of the same type, stored in a
contiguous block of memory. Arrays are particularly useful for scenarios
requiring:

  • Fixed-size collections.
  • Fast access to elements by index.
  • Compact storage of homogeneous data.

Key Characteristics

  • Fixed Size: Once created, the size of an array cannot be changed.
  • Index-based Access: Elements can be accessed using zero-based indices.
  • Mutable: Array elements can be updated.

3. Kotlin Implementations

General Array

The Array class in Kotlin can hold elements of any type. It is generic,
allowing arrays of primitive or non-primitive types.

Syntax for Creating an Array

  • Using arrayOf():
val fruits = arrayOf("Apple", "Banana", "Cherry")
// creates an array of strings

val nums = arrayOf(1, 2, 3, 4, 5)
// creates an array of integers
  • Using a Constructor:
val squares = Array(5) { it * it }
// creates an array of integers: [0, 1, 4, 9, 16]

Specialized Arrays

For better performance, Kotlin provides specialized arrays for primitive types:

  • IntArray for integers.
  • DoubleArray for doubles.
  • CharArray for characters.
  • Other types: ByteArray, ShortArray, LongArray, BooleanArray.

Syntax for Creating Specialized Arrays

  • Using intArrayOf():
val numbers = intArrayOf(1, 2, 3, 4, 5)
// creates an array of integers
  • Using a Constructor:
val evens = IntArray(5) { it * 2 }
// creates an array of integers: [0, 2, 4, 6, 8]

4. How to Use Arrays

Accessing Elements

You can access elements using indices:

val fruits = arrayOf("Apple", "Banana", "Cherry")
// array of strings

val firstFruit = fruits[0] 
// Accessing the first element (Apple)

Here using Kotlin Playground you can test this code-

Updating Elements

val fruits = arrayOf("Apple", "Banana", "Cherry")
// array of strings

fruits[1] = "Blueberry"
// Updating the second element (from Banana to Blueberry)

Here using Kotlin Playground you can test this code-

Iterating Over an Array

  • Using for Loop:
val fruits = arrayOf("Apple", "Banana", "Cherry", "Date", "Mango")
// array of strings

for (fruit in fruits) {
    println(fruit)
    // prints each fruit on a new line
}

Here using Kotlin Playground you can test this code-

  • Using forEach Function:
val fruits = arrayOf("Apple", "Banana", "Cherry", "Date", "Mango")
// array of strings

fruits.forEach { println(it) }
// prints each fruit on a new line

Here using Kotlin Playground you can test this code-

Common Operations

  • Finding Size:
val fruits = arrayOf("Apple", "Banana", "Cherry", "Date", "Mango")
// array of strings

println(fruits.size)
// Output: 5
  • Sorting:
val fruits = arrayOf("Apple", "Cherry", "Banana", "Avocado", "Date", "Mango")
val sortedFruits = fruits.sortedArray()
// sorts the array alphabetically : [Apple, Avocado, Banana, Cherry, Date, Mango]
  • Checking for Element:
val fruits = arrayOf("Apple", "Cherry", "Banana", "Avocado", "Date", "Mango")
println("Banana" in fruits)
// Output: true

5. Array Extensions in Kotlin

Kotlin provides several extension functions for arrays that make working with
them much easier. Below are some of the most useful:

  • sum(): Returns the sum of numeric elements.
val arr = arrayOf(1, 2, 3, 4, 5)
println(arr.sum())  // Output: 15
  • shuffled(): Returns a new array with elements shuffled.
val shuffledArr = arr.shuffled()
println(shuffledArr.joinToString())
  • filter(): Filters elements based on a predicate.
val evenNumbers = arr.filter { it % 2 == 0 }
println(evenNumbers.joinToString())  // Output: 2, 4
  • map(): Applies a transformation to each element.
val squared = arr.map { it * it }
println(squared.joinToString())  // Output: 1, 4, 9, 16, 25
  • sorted(): Returns a sorted array.
val sortedArr = arr.sortedArray()
println(sortedArr.joinToString())
  • take(): Returns the first n elements.
val firstThree = arr.take(3)
println(firstThree.joinToString())  // Output: 1, 2, 3
  • drop(): Returns all elements except the first n.
val withoutFirstTwo = arr.drop(2)
println(withoutFirstTwo.joinToString())  // Output: 3, 4, 5
  • distinct(): Returns an array with duplicate elements removed.
val withDuplicates = arrayOf(1, 2, 2, 3, 3, 3)
val distinctArr = withDuplicates.distinct()
println(distinctArr.joinToString())  // Output: 1, 2, 3
  • ** contains()**: Checks if an element is present in the array.
val hasThree = arr.contains(3)
println(hasThree)  // Output: true
  • indexOf(): Returns the index of the first occurrence of an element.
val index = arr.indexOf(3)
println(index)  // Output: 2
  • lastIndexOf(): Returns the index of the last occurrence of an element.
val lastIndex = arr.lastIndexOf(3)
println(lastIndex)  // Output: 2
  • count(): Returns the number of elements satisfying a condition.
val count = arr.count { it % 2 == 0 }
println(count)  // Output: 2
  • any(): Checks if any element satisfies a condition.
val hasEven = arr.any { it % 2 == 0 }
println(hasEven)  // Output: true
  • all(): Checks if all elements satisfy a condition.
val allEven = arr.all { it % 2 == 0 }
println(allEven)  // Output: false

6. Specialized or Variant Types

Specialized Arrays

Specialized arrays in Kotlin are designed for primitive types, offering enhanced performance and
memory efficiency compared to generic arrays. Below are some specialized array types available in
Kotlin:

1. IntArray

  • Primitive Type: Integer numbers
  • Description: An array for storing integers.
  • Example Syntax:
    val numbers = intArrayOf(1, 2, 3)
    
  • Example Values:
    [1, 2, 3]

2. DoubleArray

  • Primitive Type: Double-precision floating point
  • Description: An array designed for storing Double values.
  • Example Syntax:
    val decimals = doubleArrayOf(1.1, 2.2)
    
  • Example Values:
    [1.1, 2.2, 3.3]

3. FloatArray

  • Primitive Type: Single-precision floating point
  • Description: An array for storing Float values.
  • Example Syntax:
    val floats = FloatArray(3) { it * 1.0f }
    
  • Example Values:
    [0.0, 1.0, 2.0]

4. CharArray

  • Primitive Type: Characters
  • Description: An array used for storing Char values.
  • Example Syntax:
    val letters = charArrayOf('a', 'b', 'c')
    
  • Example Values:
    ['a', 'b', 'c']

5. BooleanArray

  • Primitive Type: Boolean values
  • Description: An array for storing Boolean values.
  • Example Syntax:
    val flags = booleanArrayOf(true, false)
    
  • Example Values:
    [true, false]

6. ByteArray

  • Primitive Type: 8-bit integer
  • Description: An array for storing Byte values.
  • Example Syntax:
    val bytes = byteArrayOf(1, 2, 3)
    
  • Example Values:
    [1, 2, 3]

7. ShortArray

  • Primitive Type: 16-bit integer
  • Description: An array designed to store Short values.
  • Example Syntax:
    val shorts = shortArrayOf(1000, 2000)
    
  • Example Values:
    [1000, 2000]

8. LongArray

  • Primitive Type: 64-bit integer
  • Description: An array that stores Long values.
  • Example Syntax:
    val longs = longArrayOf(100000L, 200000L)
    
  • Example Values:
    [100000, 200000]

When to Use Each Type

  • Array should be used for mixed or non-primitive types.
  • Specialized arrays like IntArray, DoubleArray, etc., are ideal for performance-critical tasks
    involving primitive types.

7. Performance and Best Practices

When to Use Arrays

  • For fixed-size collections requiring fast, index-based access.
  • When performance is critical and specialized arrays can be leveraged.

Best Practices

  1. Use the Right Type: Prefer specialized arrays for primitives to avoid
    unnecessary boxing.
  2. Use Kotlin Extension Functions: Leverage Kotlin’s rich set of array
    functions (map, filter, etc.) for cleaner code.
  3. Immutable Collections: For dynamic collections, consider using List
    instead of Array for better flexibility and safety.

8. Code Examples

Example 1: General Array

Example 2: Specialized Array - Mathematical Operations

Example 3: Real-World Use Case - Tracking Sales Over a Week

Example 4: Using Array Extensions - Filtering and Transformation

Example 5: Object Array - Working with Data Classes

Example 6: Advanced Specialized Array - Working with BooleanArray

Example 7: Advanced Real-World Use Case - Student Scores Analysis


9. Similar Data Structures

  • List vs Array: Use List for dynamic sizing; Array for fixed size.
  • MutableList vs Array: MutableList provides more flexibility for
    adding/removing elements dynamically.

10. Conclusion

Arrays in Kotlin are versatile and efficient for handling fixed-size
collections. Whether you’re working with general arrays or specialized variants,
Kotlin’s syntax and extension functions make them easy to use. By understanding
their strengths and trade-offs, you can make informed decisions about when and
how to use arrays in your applications.

Experiment with arrays in Kotlin and see how they can streamline your
programming tasks!

11. Additional Resources & References

12. Me