Collections hold almost all program data; Kotlin's read-only vs mutable split prevents accidental changes.
Kotlin distinguishes read-only collection interfaces from mutable ones:
listOf(1, 2, 3)gives aList<Int>: you can read but not add.mutableListOf()gives aMutableListwithadd,remove,set,clear.setOf/mutableSetOfhold unique elements (insertion-ordered by default, backed byLinkedHashSet).mapOf("a" to 1)/mutableMapOf()hold key-value pairs (insertion-orderedLinkedHashMap).
Read-only does not mean immutable: a List reference may point to a mutable list someone else changes. It means you can't change it through that reference, which is usually what APIs should expose.
Access:
- Lists:
list[0],list.getOrNull(5),first(),last(),size,indexOf,containsorx in list. - Maps:
map["a"]returnsV?(null when missing),getValue("a")throws if missing,getOrDefault,map["b"] = 2on mutable maps,getOrPut(key) { default }. - Iterate with
for (x in list)andfor ((k, v) in map).
Operators: list + 4 and list - 1 create new lists; += on a MutableList adds in place.
Arrays (arrayOf, intArrayOf) exist mainly for Java interop and performance; prefer lists in everyday code. emptyList(), List(5) { it * it } and buildList { add(1) } are handy builders.
Example
fun main() {
val nums = listOf(3, 1, 2)
// nums.add(4) // compile error: List is read-only
println(nums[0] + nums.last()) // 5
println(nums.getOrNull(10)) // null
println(2 in nums) // true
val todo = mutableListOf("write")
todo += "test"
todo.add(0, "plan")
println(todo) // [plan, write, test]
val tags = mutableSetOf("kotlin", "jvm")
println(tags.add("kotlin")) // false: already present
val ages = mutableMapOf("Ada" to 36)
ages["Linus"] = 28
println(ages["Grace"]) // null
println(ages.getOrPut("Grace") { 85 }) // 85
for ((name, age) in ages) print("$name=$age ") // Ada=36 Linus=28 Grace=85
println()
println(List(4) { it * it }) // [0, 1, 4, 9]
}Remember
- listOf/setOf/mapOf are read-only; mutable* variants allow changes
- map[key] returns null for missing keys
- Default sets and maps keep insertion order
- Expose read-only types from your APIs
Watch out for
- Casting a read-only List to MutableList to modify it, which can fail or change shared data.