skip to content

What does map[key] return in Kotlin when the key is absent, and how is that different from map.getValue(key)?

level: juniorimportance: must knowfreq 65%

answer

  1. [] -> get -> returns V? (nullable)
  2. getValue -> non-null or NoSuchElementException
  3. absent vs present-null ambiguity
  4. containsKey to disambiguate
  5. map[k]=v desugars to put

basics

~10 s

map[key] gives you null when the key isn't there, so the result type is nullable. map.getValue(key) instead throws an exception if the key is missing, returning a non-null value when it exists.

solid answer

~30 s

The indexing operator `map[key]` desugars to `Map.get`, whose return type is `V?` — a missing key yields `null`, so you must handle nullability. `getValue(key)` returns a non-null `V` but throws `NoSuchElementException` when the key is absent (for default LinkedHashMap-backed maps). A subtle trap: with a map whose value type is itself nullable (`Map<K, V?>`), `map[key] == null` is ambiguous — it could mean 'key absent' or 'key present with null value' — so use `containsKey` or `getOrElse` to disambiguate. Prefer `[]` for optional lookups you intend to null-check, and `getValue`/`getOrDefault`/`getOrElse` when you have a clear policy for missing keys.

go deeper

for a junior

Knows [] returns null for missing keys and getValue throws.

for a middle

Explains the absent-vs-present-null ambiguity and reaches for containsKey/getOrElse.

for a senior

Picks the right accessor by failure policy and knows withDefault changes getValue's behavior; understands []= -> put.

for a principal

Frames lookup choice as an API/error-handling contract decision and reasons about null-safety at module boundaries.

## The indexing operator In Kotlin `map[key]` is **syntactic sugar** for the `get(key)` operator function on `Map`. Its signature is: ```kotlin operator fun get(key: K): V? ``` The `?` means the result is **nullable**. A missing key returns `null`; you cannot distinguish 'absent' from 'present-but-null' by the return value alone when `V` itself is nullable. ## getValue contrasts by throwing ```kotlin val ages = mapOf("ann" to 30) val a: Int? = ages["ann"] // 30 val b: Int? = ages["bob"] // null (no exception) val c: Int = ages.getValue("ann") // 30, non-null val d: Int = ages.getValue("bob") // throws NoSuchElementException ``` `getValue` returns a **non-null** `V` and throws `NoSuchElementException` for an absent key on the standard map. (For custom maps built with `withDefault`, `getValue` returns the default instead of throwing.) ## The nullable-value trap ```kotlin val m: Map<String, Int?> = mapOf("k" to null) println(m["k"]) // null -> but key IS present! println(m.containsKey("k")) // true ``` When value type is nullable, `m[key] == null` does not prove absence. Use `containsKey`, or `getOrElse` with a sentinel, to be precise. ## Choosing - `map[key]` — you'll null-check or chain with `?.`, `?:`. - `getValue` — the key **must** exist; fail loudly otherwise. - `getOrDefault` / `getOrElse` — you have a sensible fallback. The bracket operator also has a mutating sibling for `MutableMap`: `map[key] = value` desugars to `put`.

  • How can you tell 'key absent' apart from 'key present with null value'?
    Use containsKey(key), or getOrElse with a unique sentinel object; the [] result alone can't distinguish them when values are nullable.
  • What does map[key] = value compile to?
    The set-indexing operator desugars to MutableMap.put(key, value), returning the previous value (which [] assignment discards).

saying these in an interview costs you the question

  • Claiming map[key] throws when the key is missing
  • Saying getValue returns null for absent keys
  • Ignoring the present-but-null ambiguity
  • Forgetting that [] returns a nullable type

context