Kotlin Arrays

Kotlin arrays represent fixed-size collections that hold elements of the same type or its subtypes. Unlike dynamic collections, Kotlin arrays maintain a constant size once initialized, making them ideal for performance-critical applications where memory allocation predictability matters. The Array class in Kotlin provides the foundation for all array operations, offering type safety and null safety features that distinguish it from traditional Java arrays.

Kotlin arrays are invariant, meaning you cannot assign an Array<String> to an Array<Any> to prevent runtime failures. This design choice ensures type safety throughout your application, making Kotlin arrays more reliable than their Java counterparts.

Kotlin Array Declaration Methods

Using arrayOf() Function

The arrayOf() function is the most straightforward way to create Kotlin arrays with known values:

val studentNames = arrayOf("Alice", "Bob", "Charlie", "Diana")  
val examScores = arrayOf(95, 87, 92, 88)  
val isActive = arrayOf(true, false, true, true)  

Using Array Constructor

The Array constructor accepts two parameters: array size and an initialization function:

val fibonacci = Array(10) { i ->   
    when (i) {  
        0, 1 -> 1  
        else -> fibonacci[i-1] + fibonacci[i-2]  
    }  
}  

Creating Empty Arrays

For scenarios requiring empty arrays, use the emptyArray() function:

val emptyStringArray: Array<String> = emptyArray()  
val emptyIntArray: Array<Int> = emptyArray()  

Using arrayOfNulls()

When you need arrays filled with null values initially:

val placeholderArray = arrayOfNulls<String>(5)  
// Creates: [null, null, null, null, null]  

Primitive Type Arrays in Kotlin

Kotlin provides specialized array classes for primitive types to avoid boxing overhead:

IntArray Declaration

val numbers = intArrayOf(10, 20, 30, 40, 50)  
val zeros = IntArray(5) { 0 }  
val sequence = IntArray(5) { index -> index * 2 }  

Other Primitive Arrays

val bytes = byteArrayOf(1, 2, 3, 4, 5)  
val chars = charArrayOf('K', 'o', 't', 'l', 'i', 'n')  
val doubles = doubleArrayOf(1.5, 2.7, 3.9, 4.1)  
val floats = floatArrayOf(1.0f, 2.0f, 3.0f)  
val longs = longArrayOf(100L, 200L, 300L)  
val shorts = shortArrayOf(10, 20, 30)  
val booleans = booleanArrayOf(true, false, true)  

Array Properties and Characteristics

Size Property

Every Kotlin array has a size property indicating the number of elements:

val cities = arrayOf("New York", "London", "Tokyo", "Paris")  
println("Array contains ${cities.size} cities")  
// Output: Array contains 4 cities  

Indices Property

The indices property returns a range of valid array indices:

val colors = arrayOf("Red", "Green", "Blue", "Yellow")  
for (index in colors.indices) {  
    println("Color at index $index: ${colors[index]}")  
}  

lastIndex Property

Access the last valid index directly:

val fruits = arrayOf("Apple", "Banana", "Orange")  
println("Last fruit: ${fruits[fruits.lastIndex]}")  
// Output: Last fruit: Orange  

Accessing and Modifying Array Elements

Index-based Access

Kotlin arrays use zero-based indexing for element access:

val languages = arrayOf("Java", "Kotlin", "Python", "JavaScript")  
  
// Reading elements  
val firstLanguage = languages[0]  // "Java"  
val lastLanguage = languages[3]   // "JavaScript"  
  
// Modifying elements  
languages[1] = "Scala"  
println(languages.joinToString()) // Java, Scala, Python, JavaScript  

Using get() and set() Methods

Alternative syntax for accessing array elements:

val numbers = intArrayOf(10, 20, 30, 40)  
  
// Reading with get()  
val secondNumber = numbers.get(1)  // 20  
  
// Writing with set()  
numbers.set(2, 35)  
println(numbers.joinToString()) // 10, 20, 35, 40  

Array Iteration Techniques

Enhanced For Loop

The most readable way to iterate through Kotlin arrays:

val subjects = arrayOf("Mathematics", "Physics", "Chemistry", "Biology")  
for (subject in subjects) {  
    println("Studying: $subject")  
}  

Index-based Iteration

When you need both index and value:

val grades = intArrayOf(85, 92, 78, 96, 88)  
for (i in grades.indices) {  
    println("Grade ${i + 1}: ${grades[i]}")  
}  

forEach Function

Functional approach for array iteration:

val countries = arrayOf("USA", "Canada", "Mexico", "Brazil")  
countries.forEach { country ->  
    println("Country: $country")  
}  

forEachIndexed Function

Access both index and element in functional style:

val programmingLanguages = arrayOf("C++", "Java", "Kotlin", "Python")  
programmingLanguages.forEachIndexed { index, language ->  
    println("Language $index: $language")  
}  

Array Transformation Operations

Mapping Arrays

Transform array elements using the map() function:

val temperatures = doubleArrayOf(20.5, 25.3, 18.7, 22.1)  
val fahrenheit = temperatures.map { celsius -> celsius * 9/5 + 32 }  
println("Fahrenheit: ${fahrenheit.joinToString()}")  

Filtering Arrays

Select elements based on conditions:

val scores = intArrayOf(45, 78, 92, 65, 88, 34, 91)  
val passingScores = scores.filter { it >= 60 }  
val highScores = scores.filter { it >= 90 }  
  
println("Passing scores: ${passingScores.joinToString()}")  
println("High scores: ${highScores.joinToString()}")  

Array Reduction

Combine array elements into single values:

val expenses = doubleArrayOf(25.50, 45.20, 12.75, 67.30, 33.10)  
val totalExpenses = expenses.reduce { acc, expense -> acc + expense }  
val averageExpense = expenses.average()  
  
println("Total expenses: $totalExpenses")  
println("Average expense: $averageExpense")  

Array Sorting Operations

Natural Sorting

Sort arrays according to natural order:

val randomNumbers = intArrayOf(64, 23, 87, 45, 91, 12, 56)  
val sortedAscending = randomNumbers.sorted()  
val sortedDescending = randomNumbers.sortedDescending()  
  
println("Ascending: ${sortedAscending.joinToString()}")  
println("Descending: ${sortedDescending.joinToString()}")  

Custom Sorting

Implement custom sorting logic:

val words = arrayOf("elephant", "cat", "butterfly", "dog", "ant")  
val sortedByLength = words.sortedBy { it.length }  
val sortedByLastChar = words.sortedBy { it.last() }  
  
println("By length: ${sortedByLength.joinToString()}")  
println("By last character: ${sortedByLastChar.joinToString()}")  

In-place Sorting

Modify the original array directly:

val mutableNumbers = intArrayOf(89, 23, 67, 45, 12)  
mutableNumbers.sort()  
println("Sorted in-place: ${mutableNumbers.joinToString()}")  

Array Searching and Checking Operations

Element Existence

Check if arrays contain specific elements:

val availableColors = arrayOf("red", "green", "blue", "yellow", "purple")  
  
if ("blue" in availableColors) {  
    println("Blue is available")  
}  
  
val hasRed = availableColors.contains("red")  
val hasPink = availableColors.contains("pink")  
  
println("Has red: $hasRed")  
println("Has pink: $hasPink")  

Finding Elements

Locate elements with specific criteria:

val studentAges = intArrayOf(18, 19, 20, 17, 21, 19, 18)  
  
val firstAdult = studentAges.find { it >= 18 }  
val lastTeenager = studentAges.findLast { it < 20 }  
val adultIndex = studentAges.indexOfFirst { it >= 21 }  
  
println("First adult age: $firstAdult")  
println("Last teenager age: $lastTeenager")   
println("First adult index: $adultIndex")  

Array Comparison Operations

Content Equality

Compare array contents using specialized functions:

val firstArray = arrayOf("apple", "banana", "cherry")  
val secondArray = arrayOf("apple", "banana", "cherry")  
val thirdArray = arrayOf("apple", "cherry", "banana")  
  
val areEqual = firstArray.contentEquals(secondArray)  
val areNotEqual = firstArray.contentEquals(thirdArray)  
  
println("First and second arrays equal: $areEqual")  
println("First and third arrays equal: $areNotEqual")  

Deep Comparison

For nested arrays, use contentDeepEquals():

val nestedArray1 = arrayOf(arrayOf(1, 2), arrayOf(3, 4))  
val nestedArray2 = arrayOf(arrayOf(1, 2), arrayOf(3, 4))  
  
val deepEqual = nestedArray1.contentDeepEquals(nestedArray2)  
println("Nested arrays equal: $deepEqual")  

Multidimensional Arrays

Two-dimensional Arrays

Create and work with 2D arrays:

val gameBoard = Array(3) { Array(3) { "-" } }  
  
// Set some values  
gameBoard[0][0] = "X"  
gameBoard[1][1] = "O"  
gameBoard[2][2] = "X"  
  
// Print the board  
for (row in gameBoard) {  
    println(row.joinToString(" | "))  
}  

Three-dimensional Arrays

For complex data structures:

val cube = Array(3) { Array(3) { Array(3) { 0 } } }  
  
// Fill with sequential numbers  
var counter = 1  
for (i in cube.indices) {  
    for (j in cube[i].indices) {  
        for (k in cube[i][j].indices) {  
            cube[i][j][k] = counter++  
        }  
    }  
}  

Array Conversion Operations

Array to List Conversion

Convert arrays to lists for dynamic operations:

val staticFruits = arrayOf("apple", "banana", "orange", "grape")  
val mutableFruitList = staticFruits.toMutableList()  
  
mutableFruitList.add("kiwi")  
mutableFruitList.remove("banana")  
  
println("Updated fruits: ${mutableFruitList.joinToString()}")  

Array to Set Conversion

Remove duplicates by converting to Set:

val duplicateNumbers = intArrayOf(1, 2, 3, 2, 4, 1, 5, 3)  
val uniqueNumbers = duplicateNumbers.toSet()  
  
println("Original: ${duplicateNumbers.joinToString()}")  
println("Unique: ${uniqueNumbers.joinToString()}")  

Primitive to Object Array Conversion

Convert between primitive and object arrays:

val primitiveArray = intArrayOf(10, 20, 30, 40, 50)  
val objectArray = primitiveArray.toTypedArray()  
  
println("Primitive type: ${primitiveArray::class.simpleName}")  
println("Object type: ${objectArray::class.simpleName}")  

Advanced Array Operations

Array Slicing

Extract portions of arrays:

val alphabet = arrayOf("A", "B", "C", "D", "E", "F", "G", "H")  
val firstHalf = alphabet.sliceArray(0..3)  
val lastHalf = alphabet.sliceArray(4..7)  
val middlePart = alphabet.sliceArray(2..5)  
  
println("First half: ${firstHalf.joinToString()}")  
println("Last half: ${lastHalf.joinToString()}")  
println("Middle part: ${middlePart.joinToString()}")  

Array Concatenation

Combine multiple arrays:

val firstNames = arrayOf("John", "Jane", "Bob")  
val lastNames = arrayOf("Doe", "Smith", "Johnson")  
val combinedNames = firstNames + lastNames  
  
println("Combined: ${combinedNames.joinToString()}")  

Array Partitioning

Split arrays based on conditions:

val allNumbers = intArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)  
val (evenNumbers, oddNumbers) = allNumbers.partition { it % 2 == 0 }  
  
println("Even numbers: ${evenNumbers.joinToString()}")  
println("Odd numbers: ${oddNumbers.joinToString()}")  

Practical Array Examples

Student Grade Management System

data class Student(val name: String, val grade: Double)  
  
fun demonstrateGradeSystem() {  
    val students = arrayOf(  
        Student("Alice Johnson", 92.5),  
        Student("Bob Wilson", 87.3),  
        Student("Carol Davis", 95.8),  
        Student("David Brown", 84.2),  
        Student("Emma Miller", 91.7)  
    )  
      
    // Calculate statistics  
    val averageGrade = students.map { it.grade }.average()  
    val topStudent = students.maxByOrNull { it.grade }  
    val passingStudents = students.filter { it.grade >= 85.0 }  
      
    println("Class average: $averageGrade")  
    println("Top student: ${topStudent?.name} with ${topStudent?.grade}")  
    println("Passing students: ${passingStudents.size}")  
      
    // Sort by grade descending  
    val rankedStudents = students.sortedByDescending { it.grade }  
    println("\nClass rankings:")  
    rankedStudents.forEachIndexed { index, student ->  
        println("${index + 1}. ${student.name}: ${student.grade}")  
    }  
}  

Inventory Management System

data class Product(val id: String, val name: String, val quantity: Int, val price: Double)  
  
fun demonstrateInventorySystem() {  
    val inventory = arrayOf(  
        Product("P001", "Laptop Computer", 15, 999.99),  
        Product("P002", "Wireless Mouse", 50, 29.99),  
        Product("P003", "Mechanical Keyboard", 25, 149.99),  
        Product("P004", "USB Cable", 100, 12.99),  
        Product("P005", "Monitor Stand", 8, 79.99)  
    )  
      
    // Find low stock items  
    val lowStockItems = inventory.filter { it.quantity < 20 }  
      
    // Calculate total inventory value  
    val totalValue = inventory.sumOf { it.quantity * it.price }  
      
    // Find most expensive item  
    val expensiveItem = inventory.maxByOrNull { it.price }  
      
    println("Low stock alerts:")  
    lowStockItems.forEach { product ->  
        println("${product.name}: Only ${product.quantity} left")  
    }  
      
    println("\nTotal inventory value: $${String.format("%.2f", totalValue)}")  
    println("Most expensive item: ${expensiveItem?.name} at $${expensiveItem?.price}")  
      
    // Reorder suggestions  
    val reorderList = inventory.filter { it.quantity < 15 }  
    println("\nReorder suggestions:")  
    reorderList.forEach { product ->  
        val suggestedOrder = 50 - product.quantity  
        println("${product.name}: Order $suggestedOrder units")  
    }  
}  

Weather Data Analysis

data class WeatherReading(val day: String, val temperature: Double, val humidity: Int, val rainfall: Double)  
  
fun demonstrateWeatherAnalysis() {  
    val weeklyWeather = arrayOf(  
        WeatherReading("Monday", 22.5, 65, 0.0),  
        WeatherReading("Tuesday", 25.3, 70, 2.5),  
        WeatherReading("Wednesday", 18.7, 80, 15.2),  
        WeatherReading("Thursday", 21.9, 68, 0.0),  
        WeatherReading("Friday", 26.1, 55, 0.0),  
        WeatherReading("Saturday", 28.4, 45, 0.0),  
        WeatherReading("Sunday", 24.8, 60, 1.8)  
    )  
      
    // Temperature analysis  
    val avgTemperature = weeklyWeather.map { it.temperature }.average()  
    val maxTemp = weeklyWeather.maxByOrNull { it.temperature }  
    val minTemp = weeklyWeather.minByOrNull { it.temperature }  
      
    // Rainfall analysis  
    val totalRainfall = weeklyWeather.sumOf { it.rainfall }  
    val rainyDays = weeklyWeather.filter { it.rainfall > 0.0 }  
      
    // Humidity analysis  
    val avgHumidity = weeklyWeather.map { it.humidity }.average()  
    val highHumidityDays = weeklyWeather.filter { it.humidity > 70 }  
      
    println("Weekly Weather Summary:")  
    println("Average temperature: ${String.format("%.1f", avgTemperature)}°C")  
    println("Hottest day: ${maxTemp?.day} at ${maxTemp?.temperature}°C")  
    println("Coldest day: ${minTemp?.day} at ${minTemp?.temperature}°C")  
    println("Total rainfall: ${totalRainfall}mm")  
    println("Rainy days: ${rainyDays.size}")  
    println("Average humidity: ${String.format("%.1f", avgHumidity)}%")  
      
    println("\nHigh humidity days:")  
    highHumidityDays.forEach { reading ->  
        println("${reading.day}: ${reading.humidity}% humidity")  
    }  
}  

Complete Demonstration Program

Here’s a comprehensive example showcasing various Kotlin array operations:

fun main() {  
    println("=== Kotlin Arrays Comprehensive Demo ===\n")  
      
    // Array creation and initialization  
    println("1. Array Creation:")  
    val cities = arrayOf("Tokyo", "New York", "London", "Paris", "Sydney")  
    val numbers = IntArray(5) { index -> (index + 1) * 10 }  
    val matrix = Array(3) { Array(3) { 0 } }  
      
    println("Cities: ${cities.joinToString()}")  
    println("Numbers: ${numbers.joinToString()}")  
    println("Matrix created: ${matrix.size}x${matrix[0].size}")  
      
    // Array properties and access  
    println("\n2. Array Properties:")  
    println("Cities array size: ${cities.size}")  
    println("First city: ${cities[0]}")  
    println("Last city: ${cities[cities.lastIndex]}")  
    println("Valid indices: ${cities.indices}")  
      
    // Array modification  
    println("\n3. Array Modification:")  
    val mutableCities = cities.copyOf()  
    mutableCities[2] = "Berlin"  
    println("Modified cities: ${mutableCities.joinToString()}")  
      
    // Array iteration  
    println("\n4. Array Iteration:")  
    print("Iteration with forEach: ")  
    numbers.forEach { print("$it ") }  
      
    println("\nIteration with indices:")  
    cities.forEachIndexed { index, city ->  
        println("  [$index] = $city")  
    }  
      
    // Array transformations  
    println("\n5. Array Transformations:")  
    val temperatures = doubleArrayOf(20.0, 25.5, 18.3, 22.7, 26.1)  
    val fahrenheit = temperatures.map { celsius -> celsius * 9/5 + 32 }  
    val hotDays = temperatures.filter { it > 22.0 }  
      
    println("Celsius: ${temperatures.joinToString()}")  
    println("Fahrenheit: ${fahrenheit.joinToString { String.format("%.1f", it) }}")  
    println("Hot days (>22°C): ${hotDays.joinToString()}")  
      
    // Array sorting and searching  
    println("\n6. Sorting and Searching:")  
    val scores = intArrayOf(85, 92, 78, 96, 88, 91, 87)  
    val sortedScores = scores.sorted()  
    val topScore = scores.maxOrNull()  
    val passCount = scores.count { it >= 80 }  
      
    println("Original scores: ${scores.joinToString()}")  
    println("Sorted scores: ${sortedScores.joinToString()}")  
    println("Top score: $topScore")  
    println("Passing scores (≥80): $passCount")  
      
    // Array comparisons  
    println("\n7. Array Comparisons:")  
    val array1 = arrayOf(1, 2, 3, 4, 5)  
    val array2 = arrayOf(1, 2, 3, 4, 5)  
    val array3 = intArrayOf(1, 2, 3, 4, 5)  
      
    println("Arrays equal (content): ${array1.contentEquals(array2)}")  
    println("Array to IntArray equal: ${array1.contentEquals(array3.toTypedArray())}")  
      
    // Array conversions  
    println("\n8. Array Conversions:")  
    val originalArray = arrayOf("apple", "banana", "apple", "cherry", "banana")  
    val uniqueList = originalArray.toSet().toList()  
    val mutableList = originalArray.toMutableList()  
      
    println("Original: ${originalArray.joinToString()}")  
    println("Unique items: ${uniqueList.joinToString()}")  
      
    mutableList.add("orange")  
    println("Extended list: ${mutableList.joinToString()}")  
      
    // Advanced operations  
    println("\n9. Advanced Operations:")  
    val sales = doubleArrayOf(1200.50, 1450.75, 980.25, 1680.90, 1320.60)  
    val totalSales = sales.sum()  
    val averageSales = sales.average()  
    val (highSales, lowSales) = sales.partition { it > 1300.0 }  
      
    println("Sales data: ${sales.joinToString { "$%.2f".format(it) }}")  
    println("Total sales: $%.2f".format(totalSales))  
    println("Average sales: $%.2f".format(averageSales))  
    println("High sales days: ${highSales.size}")  
    println("Low sales days: ${lowSales.size}")  
      
    // Demonstrate the practical examples  
    println("\n=== Practical Examples ===")  
    demonstrateGradeSystem()  
    println()  
    demonstrateInventorySystem()  
    println()  
    demonstrateWeatherAnalysis()  
}  
  
// Run the complete demonstration  
main()  

Key Takeaways

Kotlin arrays provide powerful data management capabilities for developers working on various applications. From basic array declaration using arrayOf() to advanced operations like filtering, mapping, and sorting, Kotlin arrays offer comprehensive functionality for handling collections of data efficiently.

Understanding array properties like size, indices, and lastIndex helps in safe array manipulation, while transformation operations enable complex data processing scenarios. The distinction between primitive arrays (IntArray, DoubleArray) and object arrays (Array<T>) allows for optimized memory usage based on specific requirements.