Map.merge în Java

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.

Sintaxă
default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remapping)

Ce face Map.merge

merge(cheie, valoare, functie) face două lucruri, în funcție de cheie: dacă cheia lipsește, pune valoare; dacă există, calculează functie(valoareVeche, valoare) și pune rezultatul. Forma cea mai des întâlnită este map.merge(cuvant, 1, Integer::sum): numără aparițiile.

Dacă funcția returnează null, perechea este ștearsă. Metoda returnează valoarea nouă (sau null dacă a fost ștearsă).

Parametri

Parametru Descriere
key Cheia.
value Valoarea pusă dacă cheia lipsește și al doilea argument al funcției.
remapping Funcția care combină valoarea veche cu cea nouă.

Ce returnează

Valoarea nouă asociată cheii sau null.

Exemple

Exemplul 1: Totalul vânzărilor pe oraș

import java.util.Map;
import java.util.TreeMap;

public class Main {
    record Vanzare(String oras, int lei) {}

    public static void main(String[] args) {
        Vanzare[] vanzari = {
            new Vanzare("Iași", 120), new Vanzare("Cluj", 80), new Vanzare("Iași", 45),
            new Vanzare("Arad", 60), new Vanzare("Cluj", 200)
        };
        Map<String, Integer> total = new TreeMap<>();
        for (Vanzare v : vanzari) {
            total.merge(v.oras(), v.lei(), Integer::sum);
        }
        System.out.println(total);
    }
}

Rezultat

{Arad=60, Cluj=280, Iași=165}

Exemplul 2: Combinarea textelor și ștergerea cu null

Funcția lipește etichetele; pentru „gata” returnează null, deci perechea dispare.

import java.util.Map;
import java.util.TreeMap;

public class Main {
    public static void main(String[] args) {
        Map<String, String> etichete = new TreeMap<>();
        etichete.merge("Ana", "urgent", (vechi, nou) -> vechi + ", " + nou);
        etichete.merge("Ana", "client nou", (vechi, nou) -> vechi + ", " + nou);
        etichete.merge("Radu", "urgent", (vechi, nou) -> vechi + ", " + nou);
        System.out.println(etichete);

        etichete.merge("Radu", "gata", (vechi, nou) -> nou.equals("gata") ? null : vechi + ", " + nou);
        System.out.println(etichete);
    }
}

Rezultat

{Ana=urgent, client nou, Radu=urgent}
{Ana=urgent, client nou}

Greșeli frecvente

  • Scrii map.put(k, map.get(k) + 1) pentru numărare. La prima apariție get dă null și apare NullPointerException; merge(k, 1, Integer::sum) tratează ambele cazuri.
  • Dai null ca valoare. merge aruncă NullPointerException; valoarea trebuie să existe.

Comenzi înrudite

  • Map.compute: compute recalculează valoarea unei chei pornind de la cea veche (sau null); computeIfPresent o face doar dacă cheia există.
  • Map.get: get returnează valoarea unei chei sau null dacă lipsește; getOrDefault returnează o valoare de rezervă în loc de null.
  • Map.putIfAbsent: Pune valoarea doar dacă cheia lipsește (sau are null). Nu suprascrie o valoare existentă; returnează valoarea care era deja.
  • Map.computeIfAbsent: Dacă cheia lipsește, calculează valoarea cu funcția dată și o pune în map. Returnează valoarea (nouă sau existentă). Ideal pentru grupări.
  • Map: Interfața pentru dicționare: perechi cheie → valoare, în care găsești rapid valoarea după cheie. Cheile sunt unice.