skip to content

Inside buildMap { }, what is 'this', and how do you add and update entries?

level: middleimportance: must knowfreq 45%

answer

  1. this == MutableMap inside the block
  2. put, this[k]=v (set operator), putAll, getOrPut
  3. Same key twice = last write wins
  4. put returns previous value
  5. Returns read-only Map

basics

~20 s

Inside the braces, 'this' is a temporary mutable map. You add entries with put or with map[key] = value, and you can overwrite existing keys the same way. When the block ends you get a read-only Map back.

solid answer

~40 s

buildMap takes a lambda with receiver `MutableMap<K, V>.() -> Unit`, so inside the block `this` is a `MutableMap<K, V>` and all its members are in scope without a qualifier. You insert with `put(key, value)`, the indexed-set operator `this[key] = value` (which compiles to `set`), `putAll(otherMap)`, or `getOrPut(key) { default }`. Because it's a real MutableMap you can also read it back mid-build with `get`/`[]` or `containsKey`, and a later `put` on an existing key overwrites the previous value — last write wins. Keys and values are inferred from the calls or declared via `buildMap<String, Int> { }`. The result is returned as read-only `Map<K, V>`. The same receiver mechanics apply to buildList (MutableList) and buildSet (MutableSet).

code

kotlin · 5 lines
kotlin
val m: Map<String, Int> = buildMap {
    put("x", 1)
    this["y"] = 2
    put("x", 9) // last write wins -> x = 9
}

go deeper

for a junior

Can add entries with put or map[k] = v and knows a read-only Map comes out.

for a middle

Explains the MutableMap receiver, the set operator, putAll/getOrPut, and last-write-wins overwrite semantics.

for a senior

Notes put's previous-value return, mid-build reads, and contrasts overwrite/no-op semantics across map vs set vs list builders.

for a principal

Reasons about using mid-build reads (getOrPut, containsKey) to build derived/aggregated maps cleanly while keeping the result immutable to callers.

## The receiver lambda `buildMap`'s signature is roughly `buildMap(builderAction: MutableMap<K, V>.() -> Unit): Map<K, V>`. The parameter type `MutableMap<K, V>.() -> Unit` is a **function literal with receiver**: when you write the lambda, `this` is bound to a freshly created `MutableMap<K, V>`. That means every member of `MutableMap` is callable unqualified inside the braces. ## Ways to add / update entries ```kotlin val config: Map<String, Int> = buildMap { put("a", 1) // explicit put this["b"] = 2 // indexed-set operator -> set(...) putAll(mapOf("c" to 3)) put("a", 10) // overwrites -> last write wins, value is now 10 getOrPut("d") { 4 } // inserts only if absent } ``` - `put(k, v)` returns the **previous** value (or null) — useful for detecting overwrites. - `this[k] = v` is the `set` operator; identical effect to `put` but discards the return. - Reading mid-build is allowed: `if ("a" !in this) put("a", 0)`. ## Overwrite semantics A map has unique keys, so putting the same key twice keeps only the last value (**last write wins**). For lists, `add` always appends; for sets, adding a duplicate is a no-op and `add` returns `false`. ## Type inference vs explicit types Keys/values are inferred from the body. If the block is empty or ambiguous, declare them: `buildMap<String, Int> { }` or annotate the target `val m: Map<String, Int> = buildMap { }`. ## Returned type The lambda receiver is mutable, but `buildMap` returns the **read-only** `Map<K, V>`. The caller cannot `put` through that reference. ## Same pattern across builders - buildList → `MutableList<T>` receiver, populate with `add`/`addAll`. - buildSet → `MutableSet<T>` receiver, `add` dedups. - buildMap → `MutableMap<K, V>` receiver, `put`/`set`/`putAll`.

  • What does put return when the key already exists?
    The previous value mapped to that key; null if the key was absent.
  • Can you read from the map while still building it?
    Yes — the receiver is a full MutableMap, so get, containsKey, and 'in' all work mid-build.

saying these in an interview costs you the question

  • Thinking 'this' is the read-only Map (it's MutableMap inside the block)
  • Believing duplicate keys throw or are kept separately (last write wins)
  • Not knowing this[k] = v maps to the set operator / put
  • Assuming you can't read the map until the block ends

context