Careeroza
Read-Only vs Mutable Collections
Two Interfaces for Each Collection
| Read-only (default) | Mutable | Create with |
|---|---|---|
List<T> | MutableList<T> | listOf / mutableListOf |
Set<T> | MutableSet<T> | setOf / mutableSetOf |
Map<K, V> | MutableMap<K, V> | mapOf / mutableMapOf |
val fruits = listOf("Apple", "Mango")
fruits.add("Banana") // ERROR: Unresolved reference 'add' (List has no add)val vs Mutable
Example
val / var is about the variable; List / MutableList is about the contents. They are independent.
fun main() {
val items = mutableListOf("A") // variable fixed, contents can change
items.add("B")
println(items)
var menu = listOf("Tea") // contents fixed, variable can point to a new list
menu = menu + "Coffee" // + creates a NEW list
println(menu)
val readOnly: List<String> = items // read-only VIEW of the same list
items.add("C")
println(readOnly) // sees the change!
val copy = items.toList() // real independent copy
items.add("D")
println(copy)
println(items)
}Output
[A, B] [Tea, Coffee] [A, B, C] [A, B, C] [A, B, C, D]
Tip: Expose List from functions and classes, keep MutableList private. Android ViewModels follow this pattern: a private mutable state and a public read-only one.
Java Comparison
In Java, List has add() even when the list is unmodifiable (it throws at run time). In Kotlin, a read-only List simply has no add(), so the mistake is caught at compile time. Both still use the same java.util.ArrayList, LinkedHashSet and LinkedHashMap classes underneath.