Adding to the end of a list
Kotlin has no built-in push function. To append an item to the end of a list, you call add on a MutableList. It takes one argument, puts it after the current last item, and makes the list one item longer:
val arr1 = mutableListOf(1, 2, 3)
arr1.add(4)
println(arr1) // [1, 2, 3, 4]
The variable is declared with val, and the code still changes the list. val means the variable always points to the same list object. It does not freeze the list's contents. Only reassigning the variable, as in arr1 = mutableListOf(9), would be an error.
MutableList or List?
Kotlin splits lists into two kinds. A List is a read-only view: you can read items and loop over them, but it has no add. A MutableList adds the functions that change the list. The helper you use to create the list decides which one you get:
mutableListOf(...)creates aMutableList.listOf(...)creates a read-onlyList.
Calling add on a list made with listOf does not compile. The compiler reports an unresolved reference to add, because the function does not exist on that type. The fix is to create the list with mutableListOf in the first place.
What add() gives you
- One item per call. To append several items, call
addseveral times, or calladdAll(listOf(...))once. - Order matters. Each new item goes after everything that is already there, so the last call ends up last.
- A return value.
addreturnstruewhen the list changed, which for a list is every time. You can ignore it, and the lesson does. - The element type is fixed. A
MutableList<Int>accepts only integers, and the compiler rejectsadd("x").
There is also a two-argument form, add(index, item), that inserts at a position and moves the later items one step to the right. With add(item), the item always goes at the end:
val fruits = mutableListOf("mango", "kiwi", "grapefruit")
fruits.add("apple")
println(fruits) // [mango, kiwi, grapefruit, apple]
fruits.add(1, "fig")
println(fruits) // [mango, fig, kiwi, grapefruit, apple]
Other ways to grow a list
Besides add, a few more forms are worth knowing:
addAll(listOf("c", "d"))appends every item of another collection, in order.fruits += "b"is shorthand forfruits.add("b")whenfruitsis declared withvaland holds aMutableList.ro + 3on a read-only list creates a new list with the extra item and leaves the original alone. Afterval ro = listOf(1, 2)andval more = ro + 3,rois still[1, 2]andmoreis[1, 2, 3].
Arrays are different. An array created with arrayOf has a fixed size and no add. If you need a collection that grows, use a MutableList.
Building a list in a loop
Appending is how you collect results one at a time. Start with an empty list, giving its element type, and add to it as you go:
val squares = mutableListOf<Int>()
for (i in 1..3) {
squares.add(i * i)
}
println(squares) // [1, 4, 9]
println(squares.size) // 3
The type in angle brackets is needed here because an empty list gives Kotlin nothing to infer it from.
The exercise
The starting code has two lists:
val fruits = mutableListOf("mango", "kiwi", "grapefruit")
val ages = mutableListOf(14, 32, 50, 21)
There are two tasks:
- Add
"apple"tofruits. One call toaddputs it after the existing three fruits, so it becomes the fourth and last item. - Add
10and23toages. Becauseaddinserts a single item per call, this takes two calls. Call it with10first and23second, so that10sits before23at the end.
The finished code:
val fruits = mutableListOf("mango", "kiwi", "grapefruit")
val ages = mutableListOf(14, 32, 50, 21)
fruits.add("apple")
ages.add(10)
ages.add(23)
Afterwards, fruits is [mango, kiwi, grapefruit, apple] and ages is [14, 32, 50, 21, 10, 23].
Common mistakes
- Using
listOf. A read-only list has noadd, so the code does not compile. - Swapping the order. Adding
23before10leaves23in the wrong place, and the list ends with..., 23, 10. - Passing two values to one call.
add(10, 23)does not append two items. With two arguments, the first is an index. - Looking for
push. The nameaddis Kotlin's way to append. Some other languages call itpushorappend.
Key takeaways
- Use
mutableListOffor a list you plan to change, andlist.add(item)to append. - Each call adds exactly one item at the end, and the list grows by one.
valprevents reassigning the variable, not changing the list.