Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Ús de mapes

Un Map<K, V> associa claus úniques a valors. És l’estructura per respondre “quin valor correspon a aquesta clau” sense haver de recórrer res:

Map<String, String> telefons = new HashMap<>();
telefons.put("Aina", "600111222");
telefons.put("Bernat", "600333444");

telefons.get("Aina");      // "600111222"
telefons.get("Carla");     // null: la clau no hi és

Una clau no es pot repetir. Si tornes a fer put() amb una clau que ja hi és, el valor antic queda substituït, i el mètode te’l retorna per si el necessites.

Operacions bàsiques

MètodeQuè fa
V put(K, V)Desa la parella i retorna el valor anterior, o null
V get(Object)El valor de la clau, o null si no hi és
boolean containsKey(Object)Si la clau hi és
V remove(Object)Treu la parella i retorna el valor que hi havia
int size(), boolean isEmpty(), void clear()Mida i buidatge

get() retorna null tant si la clau no hi és com si el valor desat és null. Si necessites distingir els dos casos, fes servir containsKey().

Recórrer un mapa

Un mapa dona tres vistes del seu contingut: keySet() amb les claus, values() amb els valors i entrySet() amb les parelles. Cada parella és un Map.Entry<K, V> amb getKey() i getValue().

for (Map.Entry<String, String> entrada : telefons.entrySet()) {
    System.out.println(entrada.getKey() + ": " + entrada.getValue());
}

Si només necessites llegir, forEach() és més curt:

telefons.forEach((nom, telefon) -> System.out.println(nom + ": " + telefon));

Recorre sempre amb entrySet() i no amb keySet() seguit d’un get() per cada clau: la segona forma torna a buscar cada clau i no aporta res.

Els mètodes que estalvien codi

Aquestes són les operacions que separen el codi de qui coneix l’API del de qui no. Comptar quantes vegades apareix cada paraula, a mà:

if (comptador.containsKey(paraula)) {
    comptador.put(paraula, comptador.get(paraula) + 1);
} else {
    comptador.put(paraula, 1);
}

I amb merge(), que rep el valor inicial i què fer si la clau ja hi era:

comptador.merge(paraula, 1, Integer::sum);

Agrupar elements en llistes, amb computeIfAbsent(), que crea el valor només si falta:

Map<Character, List<String>> perInicial = new HashMap<>();
perInicial.computeIfAbsent(nom.charAt(0), inicial -> new ArrayList<>()).add(nom);
MètodeQuan
getOrDefault(clau, valorPerDefecte)Llegir amb un valor de recanvi, en lloc de null
putIfAbsent(clau, valor)Desar només si la clau encara no hi és
computeIfAbsent(clau, funcio)Crear el valor la primera vegada, típicament una llista o un conjunt
merge(clau, inicial, funcio)Acumular: comptadors, sumes, concatenacions
compute(clau, funcio)Recalcular a partir de la clau i el valor actual

Les implementacions

Les tres implementacions es fan servir igual i només es diferencien en l’ordre de recorregut i en què demanen a les claus:

ImplementacióOrdre en recórrerRequisit de la clau
HashMapCap: pot canviar entre execucionsequals() i hashCode() ben implementats
LinkedHashMapEl d’insercióEls mateixos
TreeMapEl de les claus, de menor a majorHan de ser comparables, o cal donar un Comparator al constructor

HashMap és la tria per defecte. Passa a LinkedHashMap quan l’ordre de recorregut ha de ser previsible, per exemple si el resultat es mostra a l’usuari, i a TreeMap quan necessites recórrer per ordre de clau o buscar rangs.

Els requisits de la clau són els mateixos de què parla Comparació d’objectes, i el motiu és el mateix: HashMap col·loca les claus segons el seu hashCode(), i TreeMap les manté ordenades amb compareTo().

Mapes immutables

Map.of() crea un mapa petit i immutable en una línia, còmode per a taules de constants:

Map<String, Integer> dies = Map.of("gener", 31, "febrer", 28, "març", 31);

No admet claus ni valors null, l’ordre de recorregut no està garantit, i qualsevol intent de modificar-lo llança UnsupportedOperationException. Si el que vols és una còpia immutable d’un mapa existent, fes servir Map.copyOf(altre).

Referències

Last change: , commit: 87dfa51