Ce face Map.computeIfAbsent
computeIfAbsent(cheie, k -> valoare) apelează funcția doar dacă cheia lipsește (sau are null), pune rezultatul în map și îl returnează. Dacă cheia există, returnează valoarea existentă fără să apeleze funcția.
Cea mai cunoscută folosire este gruparea: map.computeIfAbsent(clasa, k -> new ArrayList<>()).add(elev). Prima dată creează lista goală, apoi o returnează pe aceeași de fiecare dată.
Este potrivită și ca un cache simplu: rezultatul unui calcul costisitor se calculează o dată și se păstrează. Dacă funcția returnează null, nu se adaugă nimic.
Parametri
| Parametru | Descriere |
|---|---|
key |
Cheia. |
mappingFunction |
Funcția care primește cheia și creează valoarea. |
Ce returnează
Valoarea asociată cheii după apel (sau null).
Exemple
Exemplul 1: Gruparea cuvintelor după prima literă
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
String[] orase = {"Iași", "Arad", "Cluj", "Alba Iulia", "Craiova", "Ilfov"};
Map<Character, List<String>> grupe = new TreeMap<>();
for (String o : orase) {
grupe.computeIfAbsent(o.charAt(0), k -> new ArrayList<>()).add(o);
}
System.out.println(grupe);
}
}
Rezultat
{A=[Arad, Alba Iulia], C=[Cluj, Craiova], I=[Iași, Ilfov]}
Exemplul 2: Calcul făcut o singură dată (cache)
Mesajul „calculez” apare o singură dată pentru fiecare număr.
import java.util.HashMap;
import java.util.Map;
public class Main {
static final Map<Integer, Long> cache = new HashMap<>();
static long factorial(int n) {
return cache.computeIfAbsent(n, k -> {
System.out.println("calculez " + k + "!");
long f = 1;
for (int i = 2; i <= k; i++) {
f *= i;
}
return f;
});
}
public static void main(String[] args) {
System.out.println(factorial(10));
System.out.println(factorial(10));
System.out.println(factorial(5));
}
}
Rezultat
calculez 10!
3628800
3628800
calculez 5!
120
Greșeli frecvente
- În funcție apelezi recursiv
computeIfAbsentpe același map (de exemplu Fibonacci recursiv).HashMaparuncăConcurrentModificationException. - Folosești
computeIfAbsentpentru numărare. Pentru contoare,merge(k, 1, Integer::sum)e mai potrivit.
Comenzi înrudite
Map.compute: compute recalculează valoarea unei chei pornind de la cea veche (sau null); computeIfPresent o face doar dacă cheia există.Map.putIfAbsent: Pune valoarea doar dacă cheia lipsește (sau are null). Nu suprascrie o valoare existentă; returnează valoarea care era deja.Map.merge: Pune valoarea dacă cheia lipsește; dacă există, combină valoarea veche cu cea nouă (de exemplu le adună). Ideal pentru numărători și totaluri.HashMap: Dicționarul cel mai rapid: put, get și remove în timp aproape constant, dar fără ordine garantată a cheilor.