Arrays
Reviewed & published by Brayan K
An array is a fixed-size, indexed container that holds a sequence of values of the same type, accessed by position starting at zero with the [ ] operator.
Part of the free Kotlin course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.
You'll create arrays, read and update elements, iterate by value and by index, use the primitive IntArray, and build a simple 2D grid.
What You'll Learn in This Lesson
- Creating arrays with arrayOf and intArrayOf
- Reading and updating elements by index
- Getting size and iterating with indices
- The primitive IntArray and its helpers
- How arrays differ from List and MutableList
- Building and walking a 2D array
1️⃣ Creating & Updating Arrays
Use arrayOf(...) for any type and intArrayOf(...) for efficient integer arrays. Read an element with arr[i] and update it the same way. Note that a val array can still have its elements changed — val only locks the variable, not the contents.
fun main() {
// arrayOf builds an array of any type:
val fruits = arrayOf("apple", "pear", "plum")
println(fruits[0]) // -> apple
println(fruits.size) // -> 3
// Elements are MUTABLE even though the val isn't:
fruits[1] = "peach"
println(fruits[1]) // -> peach
// intArrayOf is a specialized array of primitives:
val nums = intArrayOf(10, 20, 30)
println(nums.sum()) // -> 60
println(nums.average()) // -> 20.0
}2️⃣ Iterating: By Value and By Index
Loop the values directly with for (x in arr), or loop the positions with for (i in arr.indices) when you need the index. The indices property is a ready-made range from 0 to size - 1.
fun main() {
val colors = arrayOf("red", "green", "blue")
// Iterate values directly:
for (c in colors) print("$c ")
println() // -> red green blue
// Iterate by index using indices:
for (i in colors.indices) {
println("$i: ${colors[i]}")
}
}The primitive IntArray can be built from a size and an initializer lambda, and it ships with handy numeric helpers:
fun main() {
// IntArray(size) { init } fills each slot by index:
val squares = IntArray(5) { i -> i * i }
println(squares.toList()) // -> [0, 1, 4, 9, 16]
// Build a fixed-size array, then fill it:
val scores = IntArray(3) // -> [0, 0, 0]
scores[0] = 90
scores[2] = 75
println(scores.toList()) // -> [90, 0, 75]
println("Max: ${scores.max()}") // -> Max: 90
}3️⃣ 2D Arrays
A two-dimensional array is simply an array whose elements are themselves arrays — perfect for grids, boards, and matrices. Address a cell with two indices: grid[row][col].
fun main() {
// A 2D array is an array of arrays.
val grid = arrayOf(
intArrayOf(1, 2, 3),
intArrayOf(4, 5, 6)
)
// grid[row][col]
println(grid[0][2]) // -> 3
println(grid[1][0]) // -> 4
// Walk every cell:
for (row in grid) {
for (cell in row) print("$cell ")
println()
}
}Your turn. Fill in the ___ blanks, then run and compare.
// 🎯 YOUR TURN — replace each ___ then run main()
fun main() {
val nums = intArrayOf(4, 8, 15, 16)
// 1) Print how many elements the array has
println(nums.___) // 👉 size -> 4
// 2) Print the sum of all elements
println(nums.___()) // 👉 sum() -> 43
// ✅ Expected:
// 4
// 43
}Mini-Challenge: Grade Book
Summarize a set of test scores with size, max(), and average().
// 🎯 MINI-CHALLENGE: a tiny grade book.
// Save as GradeBook.kt and run main().
//
// Given an IntArray of test scores:
// 1. Print the number of scores.
// 2. Print the highest score (use max()).
// 3. Print the average (use average()).
//
// ✅ Expected output:
// Count: 4
// Top: 95
// Average: 80.0
fun main() {
val scores = intArrayOf(70, 80, 75, 95)
// your code here
}Common Errors (and the fix)
- ❌ arr[arr.size] throws ArrayIndexOutOfBoundsException. ✅ The last index is arr.size - 1.
- ❌ Calling arr.add(x) on an array. ✅ Arrays are fixed-size; use a MutableList to add elements.
- ❌ println(arr) prints a cryptic address. ✅ Use println(arr.toList()) or joinToString().
- ❌ Putting an Int into an arrayOf("a", "b") later. ✅ The element type is inferred; keep types consistent.
Pro Tips
- 💡 Prefer List for most day-to-day code; reach for arrays mainly for primitives or interop.
- 💡 IntArray(n) { init } is a clean way to fill an array based on its index.
- 💡 arr.indices beats 0 until arr.size for index loops.
📋 Quick Reference — Arrays
| Task | Kotlin Syntax |
|---|---|
| Make an array | arrayOf("a", "b") |
| Primitive int array | intArrayOf(1, 2, 3) |
| Sized + initializer | IntArray(5) { it * it } |
| Read / update | arr[i] / arr[i] = x |
| Size | arr.size |
| All indices | arr.indices |
| 2D access | grid[row][col] |
🎉 Lesson Complete!
- ✅ Arrays are fixed-size, zero-indexed, and accessed with [ ]
- ✅ arrayOf holds any type; intArrayOf holds efficient primitives
- ✅ Elements are mutable even in a val; the size is not
- ✅ Iterate by value or by indices
- ✅ A 2D array is an array of arrays, indexed as grid[r][c]
Practice quiz
What is the main difference between an Array and a List in Kotlin?
- An Array is always immutable
- A List cannot be indexed
- An Array has a fixed size; a MutableList can grow and shrink
- They are identical
Answer: An Array has a fixed size; a MutableList can grow and shrink. Array size is fixed at creation; use a MutableList to add or remove.
Can you change an element of a val array, e.g. arr[1] = "x"?
- Yes, val only locks the variable, not the contents
- No, val makes everything immutable
- Only the first element
- Only with mutableArrayOf
Answer: Yes, val only locks the variable, not the contents. val stops rebinding the variable, not mutating individual elements.
Why does Kotlin offer IntArray as well as Array<Int>?
- IntArray can grow dynamically
- Array<Int> is read-only
- IntArray allows mixed types
- IntArray stores raw primitive ints with no boxing
Answer: IntArray stores raw primitive ints with no boxing. IntArray avoids boxing, making it faster and more memory-efficient for numbers.
What does arr.size give you?
- The last index
- The number of elements in the array
- The memory address
- The element type
Answer: The number of elements in the array. size is the element count; the last valid index is size - 1.
What is the last valid index of an array of size 4?
- 3
- 4
- 5
- 0
Answer: 3. Arrays are zero-indexed, so the last index is size - 1 = 3.
What does IntArray(5) { i -> i * i } produce?
- [1, 4, 9, 16, 25]
- [0, 1, 2, 3, 4]
- [0, 1, 4, 9, 16]
- [5, 5, 5, 5, 5]
Answer: [0, 1, 4, 9, 16]. The initializer fills each slot by index i with i * i.
How should you print an array's contents to see the elements?
- println(arr) directly
- println(arr.toList()) or arr.joinToString()
- println(arr.address)
- println(arr.print())
Answer: println(arr.toList()) or arr.joinToString(). println(arr) shows a cryptic address; toList() or joinToString() shows elements.
What does arr.indices provide?
- The element values
- The array size as a single number
- A reversed array
- A range from 0 to size - 1
Answer: A range from 0 to size - 1. indices is a ready-made range of valid positions for index loops.
What is a 2D array in Kotlin?
- A built-in Matrix type
- An array whose elements are themselves arrays
- A list of maps
- Two separate arrays joined
Answer: An array whose elements are themselves arrays. A 2D array is an array of arrays, addressed as grid[row][col].
What happens if you call arr.add(x) on an array?
- It appends the element
- It replaces the last element
- It won't compile; arrays are fixed-size
- It returns a new array
Answer: It won't compile; arrays are fixed-size. Arrays have no add; use a MutableList to add elements.
Continue this course
- Previous: Strings & String Templates
- Next: Functions — Define functions, return values, and write single-expression functions
- Quick reference: Kotlin cheat sheet
Frequently asked questions
What is the difference between an Array and a List in Kotlin?
An Array has a FIXED size decided when you create it — you can change the value at any index, but you cannot add or remove elements. A List comes in two flavors: an immutable List (read-only) and a MutableList that can grow and shrink with add and remove. Reach for an array when you know the count up front and want index-based access or primitive performance; reach for a list when the collection size will change. Both are indexed from 0.
Why does Kotlin have IntArray as well as Array<Int>?
Array<Int> stores boxed Integer objects, while IntArray stores raw primitive int values with no boxing — making it more memory-efficient and faster for number-heavy work. There are similar specialized types like DoubleArray, LongArray, and BooleanArray. Use the primitive versions (built with intArrayOf, doubleArrayOf, and so on) whenever you are working with numbers and care about performance.
How do I print an array's contents instead of a memory address?
Printing an array directly, like println(arr), shows something like [Ljava.lang.String;@1b6d3586 because arrays use the default object representation. To see the elements, convert it first with arr.toList() or call arr.joinToString(). For example println(arr.toList()) prints [a, b, c]. This is a frequent surprise for newcomers coming from languages where arrays print their elements automatically.
Can I change the size of an array after creating it?
No. An array's length is fixed at creation. If you need to add or remove items, use a MutableList instead, or build a new array. You can, however, freely reassign individual elements by index — arr[2] = 99 is allowed even when the array is held in a val, because val only stops you from rebinding the variable, not from mutating what it points to.