Une Map stocke des paires clé-valeur
Une HashMap (de java.util) stocke des associations : chaque clé est associée à une valeur, et vous recherchez les valeurs par leur clé en temps quasi constant. Pensez à un dictionnaire : le mot est la clé, la définition est la valeur.
Les deux paramètres de type sont <KeyType, ValueType>. Ici, les clés sont des String et les valeurs des Integer. Comme avec ArrayList, vous typez généralement la variable avec l'interface Map et construisez une HashMap.
put, get et écrasement
Deux choses à intégrer :
- Une clé est unique.
putavec une clé existante remplace sa valeur et renvoie l'ancienne. getsur une clé absente renvoienull, pas une erreur. L'auto-unboxing de cenullen unintlève uneNullPointerException, une source courante de bugs.
getOrDefault évite le piège du null
Plutôt que de vérifier null à chaque fois, demandez une valeur par défaut :
C'est la manière la plus propre de gérer les recherches « peut-être présentes », et cela mène directement au pattern le plus célèbre des HashMap.
Compter les occurrences
Compter combien de fois chaque élément apparaît est la tâche par excellence d'une HashMap :
Le pattern map.put(key, map.getOrDefault(key, 0) + 1) se lit « prends le compte actuel (ou zéro), ajoute un, puis remets-le en place ». Un équivalent plus élégant est counts.merge(word, 1, Integer::sum).
Vérifier et supprimer
putIfAbsent(key, value) n'écrit que lorsque la clé est absente, utile pour l'initialisation paresseuse.
Parcourir une HashMap
La boucle la plus courante parcourt entrySet(), vous donnant chaque clé et valeur ensemble :
Si vous n'avez besoin que des clés ou que des valeurs :
Vous pouvez aussi utiliser forEach avec une lambda : ages.forEach((name, age) -> System.out.println(name + ": " + age));.
La HashMap ne conserve pas l'ordre
Une HashMap ne garantit aucun ordre d'itération : c'est celui que produit le hachage, et il peut changer d'une exécution à l'autre. Si vous avez besoin d'un ordre prévisible :
LinkedHashMappréserve l'ordre d'insertion.TreeMapmaintient les clés triées selon leur ordre naturel (ou unComparatorque vous fournissez).
Les trois implémentent l'interface Map, donc passer de l'une à l'autre ne demande qu'une seule ligne à modifier dans le constructeur.
Les clés doivent être hachables
HashMap trouve les entrées en hachant la clé, donc les méthodes hashCode() et equals() d'une clé doivent être cohérentes entre elles. Les types intégrés comme String et Integer le font déjà correctement. Si vous utilisez votre propre classe comme clé, redéfinissez à la fois equals et hashCode ; sinon, deux objets « égaux » par leur sens atterriront dans des compartiments différents et vos recherches échoueront de façon mystérieuse.
Ensuite : HashSet
Une HashMap répond à « quelle valeur est stockée sous cette clé ? ». Quand vous voulez seulement savoir si quelque chose est présent ou non (un ensemble de valeurs uniques, sans données associées), l'outil est HashSet, qui arrive ensuite.
Questions fréquentes
Comment créer une HashMap en Java ?
Déclarez-la avec deux paramètres de type (le type de la clé et le type de la valeur) et appelez le constructeur : Map<String, Integer> ages = new HashMap<>();. Ajoutez ensuite des entrées avec ages.put("Ada", 36); et lisez-les avec ages.get("Ada");. Importez java.util.HashMap et java.util.Map.
Comment parcourir une HashMap en Java ?
Parcourez map.entrySet() avec une boucle for-each pour obtenir chaque clé et valeur ensemble : for (Map.Entry<String, Integer> e : map.entrySet()) { ... }, en lisant e.getKey() et e.getValue(). Vous pouvez aussi parcourir map.keySet() pour n'avoir que les clés ou map.values() pour n'avoir que les valeurs. Notez qu'une HashMap ne conserve pas l'ordre d'insertion.
Quelle est la différence entre get et getOrDefault ?
get(key) renvoie la valeur d'une clé, ou null si la clé est absente, ce qui peut provoquer une NullPointerException si vous utilisez le résultat directement. getOrDefault(key, fallback) renvoie la valeur si elle est présente, sinon la valeur par défaut que vous passez, ce qui vous évite la vérification de null. C'est particulièrement pratique pour compter : counts.put(c, counts.getOrDefault(c, 0) + 1).