Read-only vs Mutable Collections
The till adds orders all day. The kitchen screen needs to see those orders but must never delete one by accident. Kotlin solves this with two versions of every collection type: one that only reads and one that also writes.
The rule
Read-only is a locked window, not a frozen room.
Each collection comes in a pair:
| Read-only (reading only) | Mutable (reading and writing) |
|---|---|
List — from listOf |
MutableList — from mutableListOf |
Set — from setOf |
MutableSet — from mutableSetOf |
Map — from mapOf |
MutableMap — from mutableMapOf |
A read-only type simply has no writing functions. listOf("latte").add("chai") does not compile, because List has no add.
A MutableList is also a List, so you can hand a mutable list to someone as read-only:
val orders = mutableListOf("latte")
val kitchenView: List<String> = orders // same list, read-only window
orders.add("chai")
println(kitchenView) // [latte, chai] — the kitchen sees it
kitchenView.add("mocha") // compile error: no add on ListThat is the "locked window": the kitchen cannot change the list, but it still sees every change the till makes. Read-only is not the same as immutable. To give someone a frozen snapshot, copy it: orders.toList(). To get an editable copy of a read-only list, use toMutableList().
Do not confuse this with val and var, which are about the variable:
val+MutableList→ same list forever, contents can change.var+List→ contents fixed, but the variable can be pointed at a new list.
The shortcut
Ask two separate questions: "Can the name be reassigned?" (look at val/var) and "Can the contents change through this name?" (look for Mutable in the type). Then, if the contents matter to someone else, ask "Does anyone else hold a mutable reference?"
Can the name be reassigned?
It is a
var, so yes:menu = listOf("latte", "chai")compiles.
Drills
Answer fast — trust the rule.
Which call compiles on val drinks = listOf("latte")?
val live = mutableListOf(1); val view: List<Int> = live; live.add(2). What is view?
How do you give someone a copy that will not change when your list does?
var menu = listOf("latte"). Which line compiles?
Remember
List,Set,Mapread; theirMutable…twins also write.- Read-only is a locked window: others may still change the list behind it.
val/varis about the name;Mutableis about the contents.
