Bonjour ! Dans la leçon précédente, nous avons maîtrisé ArrayList, un outil puissant pour gérer des listes ordonnées et dynamiques. Nous avons vu que chaque élément est accessible par un index numérique (0, 1, 2, ...). Mais que faire si nous voulons accéder à nos données via une clé plus parlante, comme une chaîne de caractères ou un identifiant unique ?
Aujourd'hui, nous poursuivons notre exploration du Framework des Collections Java en nous penchant sur HashMap. C'est l'implémentation la plus courante de l'interface Map, conçue pour stocker des données sous forme de paires clé-valeur. Étant donné votre expérience avec Python et PHP, ce concept devrait vous être familier : il est très similaire aux dictionnaires (dict) en Python ou aux tableaux associatifs en PHP. L'objectif de cette leçon est de vous apprendre à utiliser HashMap pour stocker, récupérer et manipuler efficacement des données associatives.
1. Le concept de Map : une association Clé-Valeur
Contrairement à une List où l'on accède aux éléments par leur position, une Map permet d'associer une valeur à une clé unique. Vous utilisez la clé pour stocker la valeur, et vous utilisez la même clé pour la récupérer plus tard. C'est une structure de données extrêmement courante en développement backend pour des cas comme :
- Stocker des paramètres de configuration.
- Représenter un objet JSON.
- Mettre en cache des données récupérées d'une base de données pour un accès rapide.
La vidéo suivante introduit ce concept avec d'excellentes analogies.
Apprendre Java #11 Map (HashMap / LinkedHashMap)
Cette vidéo de la chaîne JirAWS, intitulée "Apprendre Java #11 Map", explique très clairement le principe des paires clé-valeur.
Regardez la première partie, l'introduction, qui compare les Maps au format JSON et utilise l'analogie des casiers universitaires pour illustrer comment une clé unique permet d'accéder à une valeur.
HashMap est l'une des implémentations les plus populaires de l'interface Map. Ses principales caractéristiques sont :
- Rapidité : Les opérations d'ajout (
put), de récupération (get) et de suppression (remove) sont extrêmement rapides, en temps constant en moyenne, noté . - Non ordonnée :
HashMapne garantit pas l'ordre dans lequel les éléments sont stockés ou itérés. Si l'ordre d'insertion est important, on utilisera sa cousineLinkedHashMap. - Clés uniques : Chaque clé dans une
HashMapdoit être unique. Si vous ajoutez un élément avec une clé qui existe déjà, l'ancienne valeur sera simplement écrasée par la nouvelle.
2. Comment fonctionne HashMap ? Le rôle de hashCode() et equals()
Pour atteindre sa vitesse remarquable, HashMap utilise un mécanisme de "hachage". Sans entrer dans des détails trop complexes, voici l'idée principale, très importante pour un ingénieur logiciel :
- Lorsque vous insérez une paire (
clé,valeur),HashMapcalcule un "code de hachage" (hash code) à partir de la clé. Ce code est un simple entier. - Ce code de hachage est utilisé pour déterminer un "seau" (
bucket), une sorte de case mémoire, où la paire sera stockée. - Lorsque vous voulez récupérer la valeur avec
get(clé),HashMaprecalcule le code de hachage de la clé, retrouve instantanément le bon seau et vous retourne la valeur.

C'est ce qui explique l'importance cruciale de redéfinir correctement les méthodes equals() et hashCode() pour vos objets personnalisés si vous les utilisez comme clés, un point que nous avons déjà abordé avec ArrayList.
3. Création et manipulation d'une HashMap
Passons à la pratique. Les opérations de base sur une HashMap sont très intuitives. La vidéo suivante vous guide à travers chaque étape, de la création à la manipulation des données.
APPRENDRE LE JAVA #12 - LES HASHMAPS
La vidéo "APPRENDRE LE JAVA #12 - LES HASHMAPS" de la chaîne Graven - Développement est un excellent tutoriel pratique.
Suivez ces étapes dans la vidéo : Déclaration : Voyez comment déclarer et initialiser une HashMap en spécifiant le type de la clé et de la valeur. Ajout d'éléments : Apprenez à utiliser la méthode put() pour insérer des paires clé-valeur. Récupération d'un élément : Découvrez comment retrouver une valeur à l'aide de sa clé avec la méthode get(). Suppression d'éléments : Voyez comment supprimer une entrée avec remove() ou vider toute la map avec clear().
Exemple de code récapitulatif :
// Bonne pratique : déclarer avec l'interface Map
import java.util.Map;
import java.util.HashMap;
public class DemoHashMap {
public static void main(String[] args) {
// Crée une map pour stocker les âges des utilisateurs
// La clé est un String (pseudo), la valeur est un Integer (âge)
Map<String, Integer> agesUtilisateurs = new HashMap<>();
// 1. AJOUTER avec put()
agesUtilisateurs.put("Alice", 30);
agesUtilisateurs.put("Bob", 25);
agesUtilisateurs.put("Charlie", 35);
// Si la clé existe, put() met à jour la valeur
agesUtilisateurs.put("Bob", 26);
System.out.println("Map complète : " + agesUtilisateurs);
// 2. RÉCUPÉRER avec get()
Integer ageBob = agesUtilisateurs.get("Bob");
System.out.println("Âge de Bob : " + ageBob);
// Si la clé n'existe pas, get() retourne null
Integer ageDavid = agesUtilisateurs.get("David");
System.out.println("Âge de David : " + ageDavid); // Affiche null
// 3. SUPPRIMER avec remove()
agesUtilisateurs.remove("Charlie");
System.out.println("Map après suppression de Charlie : " + agesUtilisateurs);
// 4. MÉTHODES UTILES
System.out.println("La map contient-elle la clé 'Alice' ? " + agesUtilisateurs.containsKey("Alice"));
System.out.println("Taille de la map : " + agesUtilisateurs.size());
}
}
Pour une référence plus détaillée des méthodes disponibles, l'article suivant est une excellente ressource.
Les maps (Map) en Java - JaaJBlog
Cet article du JaaJBlog est très bien structuré et va droit au but.
Consultez le tableau dans la section "Méthodes clés de Map" pour un aperçu complet des opérations. Notez des méthodes utiles comme getOrDefault(), qui évite de recevoir null. Regardez aussi la section "HashMap" sous "Principales implémentations" pour un résumé de ses caractéristiques.
4. Parcourir une HashMap
Puisqu'il n'y a pas d'index numérique, comment parcourir tous les éléments d'une HashMap ? Il existe trois approches principales, chacune avec son cas d'usage.
- Parcourir les clés (
keySet()) : Utile si vous n'avez besoin que des clés. - Parcourir les valeurs (
values()) : Utile si seules les valeurs vous intéressent. - Parcourir les paires clé-valeur (
entrySet()) : C'est la méthode la plus courante et la plus efficace si vous avez besoin à la fois de la clé et de la valeur à chaque itération.
La fin de la vidéo de Graven illustre parfaitement comment utiliser keySet() et entrySet().
APPRENDRE LE JAVA #12 - LES HASHMAPS
Reprenons la vidéo de Graven - Développement.
Regardez attentivement le segment Parcourir la map. Il montre comment utiliser une boucle for-each avec keySet() pour obtenir les clés, puis avec entrySet() pour obtenir les paires Map.Entry, ce qui vous donne accès à la clé (getKey()) et à la valeur (getValue()).
Voici un exemple de code qui montre les trois types d'itération :
Map<String, Integer> scores = new HashMap<>();
scores.put("Maths", 18);
scores.put("Physique", 15);
scores.put("Info", 20);
// Méthode 1: Parcourir les clés
System.out.println("\n--- Clés ---");
for (String matiere : scores.keySet()) {
System.out.println(matiere);
}
// Méthode 2: Parcourir les valeurs
System.out.println("\n--- Valeurs ---");
for (Integer note : scores.values()) {
System.out.println(note);
}
// Méthode 3: Parcourir les entrées (clé + valeur) - LA MEILLEURE PRATIQUE
System.out.println("\n--- Entrées (clé/valeur) ---");
for (Map.Entry<String, Integer> entree : scores.entrySet()) {
String matiere = entree.getKey();
Integer note = entree.getValue();
System.out.println(matiere + " : " + note);
}
5. Exercice pratique : Compteur de fréquence de mots
Mettons en pratique ce que nous avons appris avec un cas d'usage classique pour HashMap : compter le nombre d'occurrences de chaque mot dans un texte.
Énoncé :
- Créez une classe
CompteurDeMotsavec une méthodemain. - Définissez une chaîne de caractères
Stringcontenant une phrase de votre choix (par exemple,"Le Java est un langage puissant et le Java est très populaire"). - Créez une
HashMap<String, Integer>pour stocker les mots et leur fréquence. La clé sera le mot (String) et la valeur sera son nombre d'occurrences (Integer). - Transformez votre phrase en un tableau de mots. Vous pouvez utiliser la méthode
toLowerCase()pour ignorer la casse, puissplit(" ")pour découper la phrase par les espaces. - Itérez sur ce tableau de mots. Pour chaque mot :
- Vérifiez s'il est déjà présent comme clé dans votre
HashMap. - S'il n'y est pas, ajoutez-le avec une valeur de
1. - S'il y est déjà, récupérez sa valeur actuelle, incrémentez-la de
1, et mettez à jour la map avec la nouvelle valeur.
- Vérifiez s'il est déjà présent comme clé dans votre
- À la fin, affichez le contenu de la
HashMappour voir le résultat.
Astuce de pro : Pour l'étape 5, au lieu d'utiliser un if/else, vous pouvez utiliser la méthode map.getOrDefault(mot, 0). Elle retourne la valeur actuelle si la clé mot existe, ou 0 (la valeur par défaut que vous spécifiez) si elle n'existe pas. Cela simplifie le code.
Cliquez ici pour voir une proposition de solution
import java.util.HashMap;
import java.util.Map;
public class CompteurDeMots {
public static void main(String[] args) {
String phrase = "Le Java est un langage puissant et le Java est très populaire auprès des développeurs Java";
// Création de la map pour stocker les fréquences
Map<String, Integer> frequences = new HashMap<>();
// Préparation du texte : tout en minuscules et sans ponctuation simple pour un comptage plus juste
String texteNettoye = phrase.toLowerCase().replaceAll("[^a-z\\s]", "");
// Découpage en mots
String[] mots = texteNettoye.split("\\s+"); // \\s+ gère les espaces multiples
// Itération sur chaque mot
for (String mot : mots) {
if (mot.isEmpty()) continue; // Ignorer les chaînes vides
// Version classique avec if/else
/*
if (frequences.containsKey(mot)) {
// Le mot existe déjà, on incrémente le compteur
int compteur = frequences.get(mot);
frequences.put(mot, compteur + 1);
} else {
// C'est la première fois qu'on voit ce mot
frequences.put(mot, 1);
}
*/
// Version plus concise avec getOrDefault()
int compteur = frequences.getOrDefault(mot, 0);
frequences.put(mot, compteur + 1);
}
// Affichage des résultats
System.out.println("Fréquence de chaque mot :");
for (Map.Entry<String, Integer> entree : frequences.entrySet()) {
System.out.println("'" + entree.getKey() + "' : " + entree.getValue());
}
}
}
Résultat attendu :
Fréquence de chaque mot :
'est' : 2
'un' : 1
'java' : 3
'des' : 1
'auprès' : 1
'et' : 1
'le' : 2
'populaire' : 1
'puissant' : 1
'langage' : 1
'très' : 1
'développeurs' : 1
Note : l'ordre d'affichage peut varier car HashMap est non ordonnée.
Conclusion
Vous avez maintenant ajouté HashMap à votre arsenal. C'est une structure de données incroyablement performante et polyvalente que vous utiliserez constamment dans vos projets backend.
Points clés à retenir :
HashMapstocke des paires clé-valeur, offrant un accès quasi instantané () aux données via la clé.- Elle est non ordonnée. L'ordre d'itération n'est pas garanti.
- Les opérations de base sont
put(key, value),get(key), etremove(key). - La meilleure façon de parcourir une
HashMapsi vous avez besoin des clés et des valeurs est d'utiliserentrySet(). - Le bon fonctionnement de
HashMaprepose sur le contratequals()/hashCode()des objets utilisés comme clés.
Dans la prochaine leçon, nous découvrirons HashSet, une collection qui garantit l'unicité de ses éléments. Vous verrez que HashSet est en fait construit sur une HashMap en interne, ce qui rendra sa compréhension très facile après la leçon d'aujourd'hui.