Question
In Kotlin, what is the difference between List and Array?
They seem to support many of the same operations, such as looping and using functions like filter. Is there any real difference in behavior, performance, or typical usage?
val names1 = listOf("Joe", "Ben", "Thomas")
val names2 = arrayOf("Joe", "Ben", "Thomas")
for (name in names1)
println(name)
for (name in names2)
println(name)
When should I use a List instead of an Array, and vice versa?
Short Answer
By the end of this page, you will understand how List and Array differ in Kotlin, even though they often look similar in simple examples. You will learn how they differ in size behavior, mutability, APIs, performance characteristics, interoperability, and common real-world usage so you can choose the right one confidently.
Concept
List and Array in Kotlin are both ordered collections, but they are not the same kind of type.
- An
Arrayis a fixed-size container that stores elements by index. - A
Listis a collection interface designed for working with ordered data at a higher level.
The key difference
The biggest practical difference is this:
Arrayhas a fixed size after creation.Listrepresents a read-only list interface in Kotlin.
That means:
val arr = arrayOf("A", "B", "C")
arr[0] = "Z" // allowed
// arr.add("D") // not allowed
val list = listOf("A", "B", "C")
// list[0] = "Z" // not allowed
// list.add("D") // not allowed
If you want a resizable list, Kotlin provides MutableList:
Mental Model
Think of an Array like a row of numbered lockers.
- The number of lockers is fixed.
- You can open locker
0,1, or2and replace what is inside. - But you cannot suddenly create more lockers in the same row.
Think of a List like a playlist view.
- You usually care about the ordered sequence of items.
- A read-only
Listsays: “Here are the songs you can look at.” - A
MutableListsays: “You may also add, remove, or reorder songs.”
So:
- Use
Arraywhen you need a fixed-size indexed container. - Use
Listwhen you want to represent ordered data in a more general and idiomatic Kotlin way.
Syntax and Examples
Creating each type
val numbersArray = arrayOf(1, 2, 3)
val numbersList = listOf(1, 2, 3)
val mutableNumbers = mutableListOf(1, 2, 3)
Accessing elements
println(numbersArray[0]) // 1
println(numbersList[0]) // 1
Changing elements
val colors = arrayOf("red", "green", "blue")
colors[1] = "yellow"
println(colors.joinToString()) // red, yellow, blue
A read-only List does not allow element replacement:
val names = listOf("Joe", "Ben", "Thomas")
// names[0] = "Sam" // error
A does:
Step by Step Execution
Consider this example:
val namesArray = arrayOf("Joe", "Ben", "Thomas")
val namesList = listOf("Joe", "Ben", "Thomas")
println(namesArray[1])
println(namesList[1])
val filteredArray = namesArray.filter { it.length > 3 }
val filteredList = namesList.filter { it.length > 3 }
println(filteredArray)
println(filteredList)
What happens step by step
namesArrayis created as anArray<String>with 3 fixed slots.namesListis created as a read-onlyList<String>with 3 elements.namesArray[1]reads the value at index1, which is"Ben".namesList[1]also reads the value at index1, which is"Ben".filter { it.length > 3 }checks each element.
Real World Use Cases
When List is commonly used
List is the default choice in most Kotlin application code.
Examples
- Returning a list of users from a service
- Passing a collection of validation errors
- Working with API results
- Rendering ordered UI items
- Filtering and mapping business data
fun getActiveUsers(): List<String> {
return listOf("Ana", "Mila", "Ravi")
}
When Array is commonly used
Array is more common when fixed-size storage or interoperability matters.
Examples
- Interacting with Java APIs that expect arrays
- Storing a fixed number of values
- Working with matrix-like indexed data
- Performance-sensitive code with primitive arrays
- Using vararg-related operations
val rgb = arrayOf(255, 128, 64)
println(rgb[0])
When is better than both
Real Codebase Usage
In real Kotlin codebases, developers usually prefer List in public APIs and only use Array when there is a specific reason.
Common pattern: expose List, keep flexibility
fun loadNames(): List<String> {
return listOf("Joe", "Ben", "Thomas")
}
Why this is common:
- callers only need to read the values
- implementation can later change internally
- the API clearly communicates intent
Common pattern: use MutableList during construction
fun collectErrors(input: List<String>): List<String> {
val errors = mutableListOf<String>()
for (item in input) {
if (item.isBlank()) {
errors.add("Blank value found")
}
}
return errors
}
This pattern is common because:
Common Mistakes
1. Thinking List and MutableList are the same
Broken expectation:
val items = listOf("a", "b")
// items.add("c") // error
Why it happens:
listOf()gives a read-onlyList- it does not support
addorremove
Use this instead:
val items = mutableListOf("a", "b")
items.add("c")
2. Thinking arrays are resizable
Broken code:
val arr = arrayOf(1, 2, 3)
// arr.add(4) // error
Why it happens:
- arrays have fixed size
- you can replace existing elements, but not grow the array directly
3. Assuming on an array returns an array
Comparisons
| Feature | List<T> | MutableList<T> | Array<T> |
|---|---|---|---|
| Ordered collection | Yes | Yes | Yes |
| Access by index | Yes | Yes | Yes |
| Replace element by index | No | Yes | Yes |
| Add/remove elements | No | Yes | No |
| Fixed size | Interface does not imply storage details | No, can grow/shrink | Yes |
| Common in Kotlin APIs | Yes | Sometimes internally |
Cheat Sheet
Quick rules
listOf(...)creates a read-onlyListmutableListOf(...)creates aMutableListarrayOf(...)creates anArrayArrayhas fixed sizeListcannot be modified through its read-only APIMutableListsupportsadd,remove, and element assignment
Common syntax
val list = listOf("a", "b")
val mutable = mutableListOf("a", "b")
val array = arrayOf("a", "b")
Read values
println(list[0])
println(array[0])
Update values
FAQ
Is Kotlin List the same as Java array?
No. A Kotlin List is a collection interface for ordered elements, while an array is a fixed-size indexed container.
Can I change elements inside a Kotlin List?
Not if it is a read-only List. Use MutableList if you need to replace, add, or remove elements.
Why do Array and List both work in for loops?
Because both are iterable in Kotlin, so the for syntax works naturally with each.
Does filter() return the same type I started with?
Not always. For arrays, filter() usually returns a List, not an array.
Which should I use by default in Kotlin?
Usually List, especially for function parameters and return types, unless you specifically need array behavior.
When should I use Array in Kotlin?
Use it for fixed-size indexed data, Java interoperability, vararg-related operations, or specialized array use cases.
Mini Project
Description
Build a small Kotlin utility that stores a fixed set of weekday names in an array and manages a changing task list with a mutable list. This demonstrates the real difference between fixed-size data and dynamically changing collections.
Goal
Create a program that uses an Array for fixed data and a MutableList for editable data, then prints useful results from both.
Requirements
- Create an
Arraycontaining the seven weekday names. - Create a
MutableListcontaining at least two tasks. - Update one existing weekday or task by index.
- Add a new task and remove one old task.
- Print all weekdays and final tasks.
- Use at least one collection function such as
filterormap.
Keep learning
Related questions
Android AlarmManager Example: Scheduling Tasks with AlarmManager
Learn how to use Android AlarmManager to schedule tasks, set alarms, and handle broadcasts with a simple beginner example.
Can You Extend a Data Class in Kotlin? Inheritance, Limits, and Better Alternatives
Learn why Kotlin data classes cannot be extended, what causes the component function clash, and which alternatives to use instead.
Fix KaptExecution Error in Android Kotlin: Data Binding and Build Generation
Learn why KaptExecution fails in Android Kotlin builds, especially with data binding and generated classes, and how to fix it step by step.