La classe HashSet est une implémentation de l'interface Set et une extension de la classe AbstractSet. De plus elle est renforcée par une table de hachage.
// Extrait de la classe hashMap public class HashSet extends AbstractSet implements Set, Cloneable, java.io.Serializable { //... public HashSet() { map = new HashMap(); } //... }
Un seul élément null est autorisé dans une instance de classe HashSet.
Les objets HashSet ne garantissent pas l'ordre des éléments durant une itération de l'ensemble, contrairement aux collections TreeSet. En effet, la fonction de hachage disperse les éléments au sein d'une collection Set.
Néanmoins, les performances des objets implémentant cette classe restent constantes pour les opérations de base, telles que l'ajout (add()), la suppression (remove()), la vérification de présence (contains()) et l'obtention de la taille(size()).
Il existe quatre constructeurs concourant à la création de collection HashSet. Le constructeur par défaut (HashSet()) 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 (HashSet(int ini)), soit la capacité initiale et le facteur de charge (HashSet(int ini, float fac)).
// par défaut HashSet ensemble = new HashSet(); // capacité initiale HashSet ensemble = new HashSet(100); // capacité initiale et facteur de charge HashSet ensemble = new HashSet(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 l'ensemble doit être recalculé la capacité de la collection HashSet 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, lorsque le taux de remplissage atteint 70 pourcents, 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 HashSet, 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 élément de la collection spécifiée sera copiée au sein de l'objet HashSet créé.
Collection collection = new Vector(); collection.add(valeur); HashSet ensemble = new HashSet(collection);
La classe HashSet comprend principalement des méthodes d'ajout (add() et addAll()), de suppression (remove(), removeAll() retainsAll() et clear()) et de vérification de présence (isEmpty(), contains() et containsAll()).
En outre, les méthodes toArray() héritées de l'interface Set permettent de renvoyer l'ensemble des éléments contenus dans la collection Set, dans un tableau.
HashSet ensemble = new HashSet(); // remplissage de la collection... Object[] tableau = ensemble.toArray(); // le type d'exécution du tableau retourné
// est celui du tableau spécifié. String[] tabString; Object[] tableauString = ensemble.toArray(tabString);
La méthode iterator() retourne un itérateur sur les éléments de l'ensemble. Cet objet Iterator fournira le seul moyen de parcourir l'ensemble sous-jacent.
Iterator valeurs = ensemble.iterator(); while(valeurs.hasNext()){ System.out.println("Elements : " + valeurs.next()); }
La classe HashSet étant renforcée par une table de hachage (HashMap), les méthodes equals() et hashCode() revêtent une importance capitale dans le fonctionnement d'un objet HashSet. Effectivement, chaque élément ajouté, recherché ou supprimé font appel à ces méthodes pour calculer le code de hachage des objets et les comparer entre eux. Par exemple, l'ajout d'une entrée entraîne la vérification de l'existence de la clé spécifiée. Dans un premier temps, un code de hachage est calculé spécifiquement par la méthode statique hash() appelant hashCode(). Puis des tests d'égalité entre les codes de hachage des clés existantes et celui de la clé fournie sont réalisés en parallèle avec un autre test d'égalité sur les objets à l'aide de la méthode statique eq() appelant equals().
Exemple [voir]// Extrait de la classe HashMap public Object put(Object key, Object value) { Object k = maskNull(key); int hash = hash(k); int i = indexFor(hash, table.length); for (Entry e = table[i]; e != null; e = e.next) { if (e.hash == hash && eq(k, e.key)) { Object oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, k, value, i); return null; } static int hash(Object x) { int h = x.hashCode(); h += ~(h << 9); h ^= (h >>> 14); h += (h << 4); h ^= (h >>> 10); return h; } static boolean eq(Object x, Object y) { return x == y || x.equals(y); }
import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; public class CollMap { public static void main(String[] args) { HashSet ensemble = new HashSet(); TreeSet ens = new TreeSet(); ens.add(new Video("Le jour le plus long", "Ken Annakin", 1962)); ens.add(new Video("Un pont trop loin", "Richard Attenborough", 1977)); ens.add(new Video("Platoon", "Oliver Stone", 1986)); ens.add(new Video("Full metal jacket", "Stanley Kubrik", 1987)); ens.add(new Video("La ligne rouge", "Terrence Malick", 1998)); ens.add(new Video("The patriot", "Roland Emmerich", 2000)); ensemble.addAll(ens); System.out.println("\nTaille de la collection 'ensemble' : " + ensemble.size()); afficherEntrees(ensemble); Set copie = copierEntrees(ensemble); Video obj = new Video("Platoon", "Oliver Stone", 1986); if(ensemble.contains(obj)){ if(ensemble.remove(new Video("Platoon", "Oliver Stone", 1986))){ System.out.println("\nL'objet a été supprimé :\n"); afficherEntrees(ensemble); } } if(copie.containsAll(ensemble)){ System.out.println("\nLes éléments de l'ensemble ensemble sont " + "tous contenus dans l'ensemble copié"); System.out.println("\nLes éléments restant dans l'ensemble copié " + copie.retainAll(ensemble)); afficherEntrees(copie); } } public static void afficherEntrees(Set ensemble){ if(!ensemble.isEmpty()){ Iterator iterateur = ensemble.iterator(); while(iterateur.hasNext()){ Object o = iterateur.next(); System.out.println(o.toString()); } } } public static Set copierEntrees(Set ensemble){ Set res = new HashSet(); if(!ensemble.isEmpty()){ Iterator iterateur = ensemble.iterator(); while(iterateur.hasNext()){ res.add(iterateur.next()); } } return res; } } |