What does the buildList { } function do, and what is the type of the value it returns?
answer
- Mutable receiver inside braces, read-only List out
- buildList / buildSet / buildMap
- Replaces mutableListOf + toList()
- No defensive copy
- Optional capacity arg
basics
~10 sbuildList gives you a temporary mutable list to fill inside the braces, then hands back a normal read-only List. You add items with add(), and the final list cannot be changed afterward.
solid answer
~40 sbuildList { } is a standard-library inline function. It creates a fresh MutableList, passes it as the receiver of the lambda (so you call add, addAll, etc. directly), and returns the populated collection typed as the read-only List<T>. The element type is inferred from what you add, or you can specify it: buildList<String> { }. The returned object is the same underlying list but exposed only through the read-only List interface, so callers can't mutate it through that reference. buildSet and buildMap behave identically for Set and Map. It is the idiomatic replacement for the older 'create a mutable list, populate it, then return it (or call toList())' pattern, and avoids a defensive copy because the builder seals the mutable reference once the lambda returns.
code
kotlin · 5 linesval list: List<Int> = buildList {
add(1)
addAll(listOf(2, 3))
}
// list is read-only here; list.add(4) would not compilego deeper
Knows buildList gives a mutable list inside the braces and returns a read-only List, and can write a basic example with add/addAll.
Explains the receiver-lambda mechanism, the buildSet/buildMap siblings, and why it replaces the mutableListOf + toList idiom without a copy.
Discusses the upcast-to-read-only return, the capacity argument, and that the returned reference cannot be mutated even though the backing type is ArrayList.
Frames it within the contract of read-only views vs true immutability and how the builder seals the only mutable reference, contrasting with hand-rolled patterns in API design.
## What buildList is `buildList` is a standard-library function (since Kotlin 1.6, experimental earlier) for constructing a read-only `List` using imperative code. You give it a lambda whose **receiver** is a `MutableList<T>`, so inside the braces `this` is the mutable list and you can call `add`, `addAll`, `remove`, etc. without naming it. ```kotlin val names: List<String> = buildList { add("Ann") addAll(listOf("Bob", "Cy")) if (includeGuest) add("Guest") } ``` ## What it returns The function **returns `List<T>`** — the read-only interface — not `MutableList<T>`. The underlying object is an `ArrayList`, but it is handed back upcast to `List<T>`, so a caller holding the result cannot mutate it through that reference. The element type `T` is inferred from the `add` calls, or supplied explicitly: `buildList<Int> { add(1) }`. ## Why it exists Before `buildList`, the idiom was: ```kotlin val result = mutableListOf<String>() result.add("a") return result // leaks a MutableList, or... return result.toList() // ...needs a defensive copy ``` `buildList` removes that boilerplate and the copy: it constructs the list, lets you fill it, and seals it as read-only in one expression. ## Sibling builders - `buildSet { }` → receiver `MutableSet<T>`, returns `Set<T>`. - `buildMap { }` → receiver `MutableMap<K, V>`, returns `Map<K, V>`; you populate with `put`, `[k] = v`, or `putAll`. All three accept an optional `capacity: Int` first argument to pre-size the backing collection: `buildList(capacity = 100) { }`. ## Key terms - **Receiver lambda**: a lambda with a receiver type, written `MutableList<T>.() -> Unit`, so `this` inside it is the mutable collection. - **Read-only interface**: `List`/`Set`/`Map` expose no mutators; `MutableList` etc. add them. `buildList` returns the read-only one.
- How do you build a map with buildMap?buildMap { put("a", 1); this["b"] = 2 } — the receiver is a MutableMap and it returns a read-only Map.
- Can you specify the element type explicitly?Yes: buildList<String> { add("x") }, useful when the lambda is empty or the type can't be inferred.
Like an assembly line: parts move freely while the product is being built, then it ships sealed in a box you can only look at.
saying these in an interview costs you the question
- Saying buildList returns a MutableList
- Claiming you must call toList() at the end (the builder already seals it)
- Thinking you call add on a variable named 'list' instead of the implicit receiver
- Confusing buildList with listOf (listOf takes elements, not a builder lambda)