La classe HashMap est une implémentation de l'interface Map et une extension de la classe AbstractMap.

// Extrait de la classe hashMap
public class HashMap extends AbstractMap
                     implements Map, Cloneable, java.io.Serializable {
  //...
}

Une seule clé null est autorisée dans une instance de classe HashMap. Par contre, les valeurs null peuvent être plusieurs, l'unicité des entrées étant assurées essentiellement par les clés.

Les objets HashMap ne garantissent pas l'ordre des éléments durant une itération de l'associations, contrairement aux collections TreeMap. En effet, la fonction de hachage disperse les éléments au sein d'une collection Map.

Néanmoins, les performances des objets implémentant cette classe restent constantes pour les opérations de base, telles que l'ajout (put()), l'extraction (get()).

Il existe quatre constructeurs concourant à la création d'une collection HashMap. Le constructeur par défaut (HashMap()) initialise l'instance avec des valeurs par défaut, soit une capacité initiale et un facteur de charge par défaut égaux respectivement à 16 et à 0.75. Toutefois, il est possible d'indiquer soit la capacité initiale seule (HashMap(int ini)), soit la capacité initiale et le facteur de charge (HashMap(int ini, float fac)).

// par défaut
HashMap associations = new HashMap();
// capacité initiale
HashMap associations = new HashMap(100);
// capacité initiale et facteur de charge
HashMap associations = new HashMap(100, 0.70f);

La capacité initiale spécifie le nombre de cases allouées initialement à l'objet. Le facteur de charge permet de déterminer à quel moment doit être recalculé la capacité de la collection HashMap afin d'accueillir éventuellement plus d'éléments. Dans le cas d'une capacité initiale de 100 et un facteur de charge de 0.70 et lorsque le taux de remplissage atteint 70 pourcents (100 * 0.70), la capacité est recalculée et l'objet est réorganisé en conséquence. Le facteur de charge influe sur les performances de l'objet HashMap, si bien qu'il est important de ne pas le paramétrer trop bas.

le dernier constructeur accepte comme argument une collection destinée à initialiser la nouvelle instance. Chaque entrée de la collection spécifiée sera copiée au sein de l'objet HashMap créé.

Map collection = new TreeMap();
collection.put(cle, valeur);
HashMap associations = new HashMap(collection);

La classe HashMap comprend deux méthodes d'ajout put() et putAll() permettant respectivement d'ajouter une seule paire clé/valeur et toutes les entrées d'une collection Map. Les méthodes d'ajout vérifient au préalable si les clés spécifiées ne sont pas déjà présentes dans la collection. Si tel est le cas, alors les valeurs correspondantes aux clés existantes sont remplacées par les nouvelles valeurs spécifiées.

Object entree = associations.put(cle, valeur);

Map collection = new TreeMap();
// Ajout d'entrées à la collection...
associations.putAll(collection);

La suppression d'une entrée spécifique par rapport à sa clé ou de la totalité des paires clé/valeur s'effectue respectivement par l'entremise de la méthode remove() ou clear().

// suppression de l'entrée correspondant à la clé passé en argument
Object entreeSupprimee = associations.remove(cle);
// suppression de toutes les entrées de la collection HashMap
associations.clear();

La méthode get() permet l'extraction d'une valeur en fonction d'une clé indiquée. L'objet retourné est du type référence Object, si bien qu'il sera nécessaire dans la plupart des cas d'utilisation, de convertir cet objet dans la type adéquat.

HashMap associations = new HashMap();
associations.put("Une clé", new StringBuffer("Une valeur");
// extraction d'une valeur
Object obj = associations.get("Une clé");
((StringBuffer)obj).setCharAt(3, '_');

La vérification de présence d'entrées, d'une clé ou d'une valeur est possible par l'intermédiaire des méthodes isEmpty(), containsKey() et containsValue().

if(associations.isEmpty())
    System.out.println("La collection est vide !");

if(associations.containsKey(cle))
    System.out.println("La clé 'cle' a été trouvée !");

if(associations.containsValue(valeur))
    System.out.println("La valeur 'valeur' a été trouvée !");

La taille de l'objet HashMap, soit le nombre d'entrées contenues, est retourné par la méthode size().

int taille = associations.size();

En outre, la collection HashMap comporte plusieurs méthodes capables d'extraire la totalité des entrées, ou uniquement les clés ou les valeurs stockées dans l'objet TreeMap.

HashMap associations = new HashMap();
// remplissage de la collection...
// Toutes les clés sont stockées dans la collection Set
Set cles = associations.keySet();
// Toutes les valeurs sont stockées dans l'objet Collection.
Collection valeurs = associations.values();

La méthode entrySet() retourne toutes les entrées de l'objet HashMap au sein d'un ensemble Set. Le contenu de cette collection Set est un ensemble d'objets Map.Entry contenant la clé et la valeur de chaque paire clé/valeur de l'objet HashMap.

Set entrees = associations.entrySet();
Iterator iterateur = entrees.iterator();
while(iterateur.hasNext()){
  Map.Entry entree = (Map.Entry)iterateur.next();
  System.out.println(entree.getKey() + " " + entree.getValue());
}

Les méthodes equals() et hashCode() revêtent une importance capitale dans le fonctionnement d'un objet HashMap. Effectivement, chaque entrée ajoutée, recherchée ou supprimée fait appel à ces méthodes pour calculer le code de hachage des objets clés et les comparer entre eux.

Exemple [voir]
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.Map;
import java.util.TreeMap;

public class CollMap {
  private static TreeMap assocTreeMap = new TreeMap();

  public static void main(String[] args) {
    HashMap associations = new HashMap();
    associations.putAll(assocTreeMap);

    System.out.println("Taille de la collection 'associations' : " + associations.size());
    afficherEntrees(associations);

    Video obj = new Video("Platoon", "Oliver Stone", 1986);
    if(associations.containsKey(obj))
      System.out.println(System.out.println("\nL'objet ci-dessous a été supprimé :\n" 
        + associations.remove(new Video("Platoon", "Oliver Stone", 1986)));
    System.out.println("\nTaille de la collection 'associations' : " + associations.size());
    afficherEntrees(associations);

    Set entrees = associations.entrySet();
    Iterator iterateur = entrees.iterator();
    System.out.println("\nListe des entrées (clé - valeur)");
    while(iterateur.hasNext()){
      Map.Entry entree = (Map.Entry)iterateur.next();
      System.out.println(entree.getKey() + " - " + entree.getValue());
    }
  }
  public static void afficherEntrees(Map assoc){
    Set ensemble = assoc.keySet();
    int taille = assoc.size();
    if(!assoc.isEmpty()){
      Iterator iterateur = ensemble.iterator();
      while(iterateur.hasNext()){
        Object o = iterateur.next();
        System.out.println(o.toString() + " : " + assoc.get(o));
      }
    }
  }
  public static void ajoutTreemap(){
    assocTreeMap.put(new Video("Le jour le plus long", "Ken Annakin", 1962), 
                   "Le débarquement en Normandie par les troupes alliées " 
                 + "le 6 juin 1944. Un casting prestigieux pour un film " 
                 + "de guerre d'anthologie.");
  assocTreeMap.put(new Video("Un pont trop loin", "Richard Attenborough", 1977), 
                   "La plus grande opération aéroportée sur les ponts entre " 
                 + "la France et l'Allemagne, doit précipiter la chute de "
                 + "l'Allemagne nazie.");
  assocTreeMap.put(new Video("Platoon", "Oliver Stone", 1986), 
                   "Ce film choc sur la guerre du Vietnam, met en "
                 + "scène un peloton du 25eme régiment d'infanterie "
                 + "gangréné par des luttes intestinales.");
  assocTreeMap.put(new Video("Full metal jacket", "Stanley Kubrik", 1987), 
                 + ""Cette épopée de la guerre du Vietnam raconte "
                 + "l'évolution de jeunes Marines durant un entraînement "
                 + "impitoyable et jusqu'à une réalité sanglante des "
                 + "combats lors des offensives du tet à Hue.");
  assocTreeMap.put(new Video("La ligne rouge", "Terrence Malick", 1998), 
                   "Ce film décrit la bataille de Guadalcanal et ses "
                 + "terribles affrontements entre soldats américains "
                 + "et japonais dans une île aux paysages paradisiaques.");
  assocTreeMap.put(new Video("The patriot", "Roland Emmerich", 2000), 
                 + ""Lors de la guerre d'indépendance américaine en 1776, "
                 + "un père tente de sauvegarder ses enfants de la barbarie "
                 + "d'une guerre fratricide, mais ne peut empêcher d'y être "
                 + "plongé malgrè lui.");
  }
}

//Classe Video
import java.util.GregorianCalendar;
import java.util.Calendar;

public class Video implements Comparable {
  private String titre, realisateur;
  private int annee;
  
  public Video(){
    this("Inconnu", "Inconnu", 0);
  }
    public Video (String[] infos) {
      this(infos[0], infos[1], Integer.parseInt(infos[3]));
    }
    public Video (String titre, String realisateur){
      this(titre, realisateur, (new GregorianCalendar()).get(Calendar.YEAR));
    }
  public Video (String titre, String realisateur, String annee){
    this(titre, realisateur, Integer.parseInt(annee));
  }
  public Video (String titre, String realisateur, int annee){
    if (titre == null || realisateur == null)
      throw new NullPointerException();
    this.titre = titre;
    this.realisateur = realisateur;
    this.annee = annee;
  }
  
  public String obtenirTitre(){
    return this.titre;
  }
  public String obtenirRealisateur(){
    return this.realisateur;
  }
  public int obtenirAnnee(){
    return this.annee;
  }

  public void fournirTitre(String titre){
    this.titre = titre;
  }
  public void fournirRealisateur(String realisateur){
    this.realisateur = realisateur;
  }
  public void fournirAnnee(int annee){
    this.annee = annee;
  }
  
  public int hashCode(){
    return annee * titre.hashCode() + realisateur.hashCode();
  }
  
  public boolean equals(Object o){
    if(!(o instanceof Video))
      return false;
    Video v = (Video)o;
    if(this.hashCode() == v.hashCode())
      return true;
    return false;
  }
  
  public int compareTo(Object o){
    if(!(o instanceof Video))
      throw new ClassCastException();
    Video v = (Video)o;
    int comparaison;
    if((comparaison = titre.compareTo(v.obtenirTitre())) != 0)
      return  comparaison;
    else if((comparaison = realisateur.compareTo(v.obtenirRealisateur())) != 0)
      return comparaison;
    else
      return (new Integer(annee)).compareTo(new Integer(v.obtenirAnnee()));
  }
  
  public String toString(){
    StringBuffer res = new StringBuffer("[");
    res.append(titre);
    res.append(", ");
    res.append(realisateur);
    res.append(", ");
    res.append(annee);
    return res.append("]").toString();
  }
}