skip to content

Array & Primitive Array Types

Array<T> boxes its elements while IntArray and friends map to real JVM primitive arrays, which is why the conversion functions exist. Interviewers use this to check you know when arrays still beat lists and why Kotlin keeps both.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

How do you create an array in Kotlin and read/write its elements?

level: juniorimportance: must knowfreq 70%

answer

  1. arrayOf(...) and Array(size) { it }
  2. [] = get/set, zero-based
  3. fixed size, no add/remove
  4. size, lastIndex, indices
  5. val locks reference, not elements

basics

~10 s

Use arrayOf(1, 2, 3) to make one, then read or change an element with square brackets like a[0] or a[0] = 9. Get the length with a.size.

solid answer

~30 s

Create arrays with the factory functions: arrayOf("a", "b") for an Array<String>, or the Array(size) { index -> ... } constructor that fills each slot from a lambda. Access uses the indexing operator [], which compiles to get(index)/set(index, value). Out-of-bounds access throws IndexOutOfBoundsException. The number of elements is a.size, indices run 0 until size. Arrays have a FIXED size after creation — there is no add/remove. Useful helpers: arrayOfNulls<T>(n) (all null, type Array<T?>), emptyArray<T>(), and lastIndex. Unlike a List, an array's contents are always mutable in place even though the reference can be a val.

code

kotlin · 5 lines
kotlin
val a = Array(3) { it + 1 }   // [1, 2, 3]
a[2] = 99                      // set
println(a[2])                  // 99
println(a.size)                // 3
// a[3] -> IndexOutOfBoundsException

go deeper

for a junior

Creates with arrayOf, reads/writes with [], knows .size and zero-based indexing.

for a middle

Reaches for the Array(size) { } constructor and arrayOfNulls/emptyArray, and explains the fixed-size nature.

for a senior

Articulates the get/set operator desugaring, val-vs-contents mutability, and when to choose arrays over List.

for a principal

Frames arrays as low-level interop/perf tools, steering teams toward List by default and reserving arrays for varargs, buffers, and primitive performance.

## What an array is A Kotlin **array** is a fixed-size, indexable container of elements of one type, represented by the `Array<T>` class (which maps to a JVM object array). Once created its **length never changes** — you can replace elements but not add or remove them. ## Creating arrays - **`arrayOf(...)`** — vararg factory: `val a = arrayOf(1, 2, 3)` infers `Array<Int>`. - **`Array(size) { index -> value }`** — the constructor that computes each element from its index: `val sq = Array(5) { it * it }` gives `[0, 1, 4, 9, 16]`. - **`arrayOfNulls<String>(3)`** — an `Array<String?>` filled with `null`. - **`emptyArray<Int>()`** — a zero-length array. ```kotlin val names = arrayOf("Ann", "Bo") val table = Array(3) { i -> i * 10 } // [0, 10, 20] names[0] = "Cy" // set println(names[1]) // get -> "Bo" println(names.size) // 2 println(names.lastIndex) // 1 ``` ## Indexing The `[]` syntax is the **indexing operator**: `a[i]` calls `a.get(i)` and `a[i] = x` calls `a.set(i, x)`. Indices are zero-based, valid range `0 until size`. Reading or writing outside that range throws **`IndexOutOfBoundsException`**. ## Size and iteration - `a.size` — element count; `a.lastIndex` — `size - 1`. - `a.indices` — the `IntRange` `0..lastIndex`. - Iterate with `for (x in a)`, `for (i in a.indices)`, or `a.forEachIndexed { i, x -> ... }`. ## val vs contents A `val a = arrayOf(...)` makes the **reference** immutable, but the **elements are still mutable** (`a[0] = ...` is legal). Arrays are not read-only the way `List` is. ## When to use Prefer `List`/`MutableList` for most code (richer API, safer). Reach for arrays for interop, fixed-size buffers, varargs (`vararg` parameters are arrays), or primitive-array performance (see `IntArray`).

  • If I declare the array with val, can I still change its elements?
    Yes. val only freezes the reference; a[i] = x still works because the array's contents are mutable.
  • How is Array(n) { ... } different from arrayOfNulls<T>(n)?
    Array(n) { ... } runs the lambda to initialize every slot to a real value; arrayOfNulls fills all slots with null and gives type Array<T?>.

An array is like a row of numbered mailboxes: a fixed count of slots you can refill, but you cannot bolt on a new mailbox.

saying these in an interview costs you the question

  • Thinking arrays can grow with add()/remove()
  • Believing val makes elements unmodifiable
  • Confusing size (a property) with a length() method
  • Expecting one-based indexing
  • Not knowing out-of-bounds throws IndexOutOfBoundsException

context

open as a page

What is the difference between Array<Int> and IntArray in Kotlin, and why does it matter?

level: middleimportance: must knowfreq 75%

basics

~10 s

Array<Int> stores boxed Integer objects; IntArray stores raw int values directly. IntArray uses less memory and is faster because it skips the boxing, so prefer it for numbers.

open as a page

Walk through the conversions between Array<T>, primitive arrays, and collections (toTypedArray, toIntArray, toList, etc.).

level: middleimportance: should knowfreq 60%

basics

~10 s

Use toTypedArray() to get an Array<T>, toIntArray()/toLongArray() for primitive arrays, and toList()/toMutableList() for collections. Each one copies the data into a new container.

open as a page

Why does == on two arrays with equal contents return false, and how do you compare arrays correctly?

level: seniorimportance: should knowfreq 55%

basics

~10 s

For arrays, == checks identity (same object), not contents, so two different arrays with the same values are not equal. Use contentEquals() to compare values, and contentHashCode()/contentToString() for hashing and printing.

open as a page

Explain array variance in Kotlin: why is Array<T> invariant, and how do primitive arrays and varargs relate to Java's covariant arrays?

level: principalimportance: nice to knowfreq 30%

basics

~10 s

In Kotlin you cannot pass an Array<String> where an Array<Any> is expected — arrays are invariant. This prevents a class of runtime errors that Java's covariant arrays allow.

open as a page