MutableMap.getOrPut în Kotlin

Întoarce valoarea cheii; dacă lipsește, o calculează cu lambda, o salvează în map și o întoarce.

Sintaxă
fun <K, V> MutableMap<K, V>.getOrPut(cheie: K, valoareNoua: () -> V): V

Ce face MutableMap.getOrPut

getOrPut(cheie) { ... } verifică dacă cheia există. Dacă da, întoarce valoarea ei. Dacă nu, rulează lambda, pune rezultatul în map pentru acea cheie și îl întoarce.

Este modul obișnuit de a construi un map de liste („pune elevul în lista orașului lui, creând lista dacă nu există”) sau de a ține un cache: un rezultat scump se calculează o singură dată, apoi se citește din map.

Parametri

Parametru Descriere
cheie Cheia căutată.
valoareNoua Lambda care produce valoarea, executată doar dacă cheia lipsește.

Ce returnează

Valoarea existentă sau cea nou creată (și salvată).

Exemple

Exemplul 1: Map de liste

Pentru fiecare oraș, getOrPut întoarce lista existentă sau creează una goală. Apoi adăugăm numele în ea.

fun main() {
    val inscrieri = listOf("Ana" to "Iași", "Ion" to "Cluj", "Maria" to "Iași", "Dan" to "Cluj", "Ioana" to "Arad")
    val peOrase = mutableMapOf<String, MutableList<String>>()
    for ((nume, oras) in inscrieri) {
        peOrase.getOrPut(oras) { mutableListOf() }.add(nume)
    }
    println(peOrase)
}

Rezultat

{Iași=[Ana, Maria], Cluj=[Ion, Dan], Arad=[Ioana]}

Exemplul 2: Cache pentru un calcul scump

Mesajul „calculez” apare doar prima dată pentru fiecare număr. A doua cerere pentru 5 vine direct din map.

val cache = mutableMapOf<Int, Long>()

fun fibonacci(n: Int): Long = cache.getOrPut(n) {
    println("calculez $n")
    if (n < 2) n.toLong() else fibonacci(n - 1) + fibonacci(n - 2)
}

fun main() {
    println(fibonacci(5))
    println(fibonacci(5))
    println("În cache: ${cache.keys}")
}

Rezultat

calculez 5
calculez 4
calculez 3
calculez 2
calculez 1
calculez 0
5
5
În cache: [1, 0, 2, 3, 4, 5]

Greșeli frecvente

  • Folosești getOrPut pe un map în care valoarea poate fi null: o valoare null salvată este tratată ca lipsă și lambda rulează din nou.
  • Scrii if (k !in map) map[k] = ...; map[k]!!: getOrPut face asta într-un singur pas, fără !!.

Comenzi înrudite

  • Map.getValue: Citește valoarea unei chei: getValue aruncă excepție dacă lipsește, getOrDefault și getOrElse dau o valoare de rezervă.
  • MutableMap.put: Adaugă o cheie cu valoarea ei sau înlocuiește valoarea unei chei existente; putAll copiază toate intrările altui map.
  • Iterable.groupBy: Împarte elementele în grupe după o cheie și întoarce un map: cheie → lista elementelor din acea grupă.
  • MutableMap.merge: Pune valoarea dacă cheia lipsește; dacă există, o combină cu cea veche folosind funcția dată (de exemplu adunare).