logo

HashSet en Java

Jeu de hachage Java La classe implémente l'interface Set, soutenue par une table de hachage qui est en fait une instance de HashMap. Aucune garantie n'est faite quant à l'ordre d'itération des jeux de hachage, ce qui signifie que la classe ne garantit pas l'ordre constant des éléments dans le temps. Cette classe autorise l'élément null. La classe offre également des performances en temps constant pour les opérations de base telles que l'ajout, la suppression, le contenu et la taille en supposant que la fonction de hachage disperse correctement les éléments entre les compartiments, ce que nous verrons plus loin dans l'article.

Fonctionnalités Java HashSet

Quelques fonctionnalités importantes de HashSet sont mentionnées ci-dessous :

  • Met en oeuvre Définir l'interface .
  • La structure de données sous-jacente pour HashSet est Table de hachage .
  • Comme il implémente l'interface Set, les valeurs en double ne sont pas autorisées.
  • Il n'est pas garanti que les objets que vous insérez dans HashSet soient insérés dans le même ordre. Les objets sont insérés en fonction de leur code de hachage.
  • Les éléments NULL sont autorisés dans HashSet.
  • HashSet implémente également Sérialisable et Clonable interfaces.

Déclaration de HashSet

public class HashSet extends AbstractSet implements Set, Cloneable, Serializable>

ET est le type d'éléments stockés dans un HashSet.



Exemple Java de HashSet

Java




// Java program to illustrate the concept> // of Collection objects storage in a HashSet> import> java.io.*;> import> java.util.*;> > class> CollectionObjectStorage {> > >public> static> void> main(String[] args)> >{> >// Instantiate an object of HashSet> >HashSet set =>new> HashSet();> > >// create ArrayList list1> >ArrayList list1 =>new> ArrayList();> > >// create ArrayList list2> >ArrayList list2 =>new> ArrayList();> > >// Add elements using add method> >list1.add(>1>);> >list1.add(>2>);> >list2.add(>1>);> >list2.add(>2>);> >set.add(list1);> >set.add(list2);> > >// print the set size to understand the> >// internal storage of ArrayList in Set> >System.out.println(set.size());> >}> }>

chaîne java en json
>

>

Sortir:

1>

Avant de stocker un objet, HashSet vérifie s'il existe une entrée existante à l'aide des méthodes hashCode() et equals(). Dans l’exemple ci-dessus, deux listes sont considérées comme égales si elles contiennent les mêmes éléments dans le même ordre. Lorsque vous invoquez le code de hachage() méthode sur les deux listes, elles donneraient toutes les deux le même hachage puisqu’elles sont égales.

Note: HashSet fait ne pas stocker les éléments en double , si vous donnez deux objets égaux, il ne stocke que le premier, ici list1.

La hiérarchie de HashSet est la suivante :

Fonctionnement interne d'un HashSet

Toutes les classes de l'interface Set sont sauvegardées en interne par Map. HashSet utilise HashMap pour stocker son objet en interne. Vous devez vous demander que pour saisir une valeur dans HashMap, nous avons besoin d'une paire clé-valeur, mais dans HashSet, nous ne transmettons qu'une seule valeur.

Stockage dans HashMap : En fait, la valeur que nous insérons dans HashSet agit comme une clé de l'objet map et pour sa valeur, Java utilise une variable constante. Ainsi, dans la paire clé-valeur, toutes les valeurs seront les mêmes.

Implémentation de HashSet dans la documentation Java

private transient HashMap map; // Constructor - 1 // All the constructors are internally creating HashMap Object. public HashSet() { // Creating internally backing HashMap object map = new HashMap(); } // Constructor - 2 public HashSet(int initialCapacity) { // Creating internally backing HashMap object map = new HashMap(initialCapacity); } // Dummy value to associate with an Object in Map private static final Object PRESENT = new Object();>

Si nous regardons le ajouter() méthode de la classe HashSet :

public boolean add(E e) { return map.put(e, PRESENT) == null; }>

On peut remarquer que la méthode add() de la classe HashSet appelle en interne le mettre() méthode de sauvegarde de l'objet HashMap en passant l'élément que vous avez spécifié comme clé et la constante PRESENT comme valeur. retirer() la méthode fonctionne également de la même manière. Il appelle en interne la méthode Remove de l’interface Map.

public boolean remove(Object o) { return map.remove(o) == PRESENT; }>

HashSet stocke non seulement des objets uniques, mais également une collection unique d'objets comme Liste des tableaux , Liste liée , Vecteur,..etc.

Constructeurs de la classe HashSet

Pour créer un HashSet, nous devons créer un objet de la classe HashSet. La classe HashSet se compose de différents constructeurs qui permettent la création éventuelle du HashSet. Voici les constructeurs disponibles dans cette classe.

1. HashSet()

Ce constructeur est utilisé pour créer un objet HashSet vide dans lequel la capacité initiale par défaut est de 16 et le facteur de charge par défaut est de 0,75. Si nous souhaitons créer un HashSet vide avec le nom hs, alors il peut être créé comme :

HashSet hs = new HashSet();>

2. HashSet (int initialCapacity)

Ce constructeur est utilisé pour construire un objet HashSet vide dans lequel initialCapacity est spécifié au moment de la création de l'objet. Ici, le loadFactor par défaut reste 0,75.

HashSet hs = new HashSet(int initialCapacity);>

3. HashSet (int initialCapacity, float loadFactor)

Ce constructeur est utilisé pour créer un objet HashSet vide dans lequel initialCapacity et loadFactor sont spécifiés au moment de la création de l'objet.

HashSet hs = new HashSet(int initialCapacity, float loadFactor);>

4. HashSet (Collection)

Ce constructeur est utilisé pour construire un objet HashSet contenant tous les éléments de la collection donnée. En bref, ce constructeur est utilisé lorsqu'une conversion est nécessaire d'un objet Collection vers l'objet HashSet. Si nous souhaitons créer un HashSet avec le nom hs, il peut être créé comme :

HashSet hs = new HashSet(Collection C);>

Vous trouverez ci-dessous la mise en œuvre des sujets ci-dessus :

Java




// Java program to Demonstrate Working> // of HashSet Class> > // Importing required classes> import> java.util.*;> > // Main class> // HashSetDemo> class> GFG {> > >// Main driver method> >public> static> void> main(String[] args)> >{> > >// Creating an empty HashSet> >HashSet h =>new> HashSet();> > >// Adding elements into HashSet> >// using add() method> >h.add(>'India'>);> >h.add(>'Australia'>);> >h.add(>'South Africa'>);> > >// Adding duplicate elements> >h.add(>'India'>);> > >// Displaying the HashSet> >System.out.println(h);> >System.out.println(>'List contains India or not:'> >+ h.contains(>'India'>));> > >// Removing items from HashSet> >// using remove() method> >h.remove(>'Australia'>);> >System.out.println(>'List after removing Australia:'> >+ h);> > >// Display message> >System.out.println(>'Iterating over list:'>);> > >// Iterating over hashSet items> >Iterator i = h.iterator();> > >// Holds true till there is single element remaining> >while> (i.hasNext())> > >// Iterating over elements> >// using next() method> >System.out.println(i.next());> >}> }>

>

>

Sortir:

[South Africa, Australia, India] List contains India or not:true List after removing Australia:[South Africa, India] Iterating over list: South Africa India>

Méthodes dans HashSet

MÉTHODE

DESCRIPTION

ajouter(Et et) Utilisé pour ajouter l'élément spécifié s'il n'est pas présent, s'il est présent, renvoie false.
clair() Utilisé pour supprimer tous les éléments de l'ensemble.
contient (Objet o) Utilisé pour renvoyer true si un élément est présent dans un ensemble.
supprimer (Objet o) Utilisé pour supprimer l'élément s'il est présent dans l'ensemble.
itérateur() Utilisé pour renvoyer un itérateur sur l'élément de l'ensemble.
est vide() Utilisé pour vérifier si l'ensemble est vide ou non. Renvoie vrai pour vide et faux pour une condition non vide pour set.
taille() Utilisé pour renvoyer la taille de l'ensemble.
cloner() Utilisé pour créer une copie superficielle de l'ensemble.

Effectuer diverses opérations sur HashSet

Voyons comment effectuer quelques opérations fréquemment utilisées sur le HashSet.

1. Ajout d'éléments dans HashSet

Pour ajouter un élément au HashSet, nous pouvons utiliser la méthode add() . Cependant, l'ordre d'insertion n'est pas conservé dans le HashSet. Nous devons noter que les éléments en double ne sont pas autorisés et que tous les éléments en double sont ignorés.

Exemple

Java




// Java program to Adding Elements to HashSet> > // Importing required classes> import> java.io.*;> import> java.util.*;> > // Main class> // AddingElementsToHashSet> class> GFG {> > >// Method 1> >// Main driver method> >public> static> void> main(String[] args)> >{> >// Creating an empty HashSet of string entities> >HashSet hs =>new> HashSet();> > >// Adding elements using add() method> >hs.add(>'Geek'>);> >hs.add(>'For'>);> >hs.add(>'Geeks'>);> > >// Printing all string el=ntries inside the Set> >System.out.println(>'HashSet elements : '> + hs);> >}> }>

>

>

Sortir:

HashSet elements : [Geek, For, Geeks]>

2. Suppression d'éléments dans HashSet

Les valeurs peuvent être supprimées du HashSet à l'aide de la méthode remove().

Exemple

Java




// Java program Illustrating Removal Of Elements of HashSet> > // Importing required classes> import> java.io.*;> import> java.util.*;> > // Main class> // RemoveElementsOfHashSet> class> GFG {> > >// Main driver method> >public> static> void> main(String[] args)> >{> >// Creating an> >HashSet hs =>new> HashSet();> > >// Adding elements to above Set> >// using add() method> >hs.add(>'Geek'>);> >hs.add(>'For'>);> >hs.add(>'Geeks'>);> >hs.add(>'A'>);> >hs.add(>'B'>);> >hs.add(>'Z'>);> > >// Printing the elements of HashSet elements> >System.out.println(>'Initial HashSet '> + hs);> > >// Removing the element B> >hs.remove(>'B'>);> > >// Printing the updated HashSet elements> >System.out.println(>'After removing element '> + hs);> > >// Returns false if the element is not present> >System.out.println(>'Element AC exists in the Set : '> >+ hs.remove(>'AC'>));> >}> }>

>

>

Sortir:

Initial HashSet [A, B, Geek, For, Geeks, Z] After removing element [A, Geek, For, Geeks, Z] Element AC exists in the Set : false>

3. Itérer dans le HashSet

Parcourez les éléments de HashSet à l’aide de la méthode iterator(). Aussi, la plus connue consiste à utiliser le amélioré pour la boucle.

Exemple

Bloc de code

Sortir

A, B, Geek, For, Geeks, Z, A, B, Geek, For, Geeks, Z,>

Complexité temporelle des opérations HashSet : La structure de données sous-jacente de HashSet est une table de hachage. Donc, amortissez (moyenne ou cas habituel) la complexité temporelle nécessaire à l'ajout, à la suppression et à la recherche (méthode contient) de HashSet. O(1) temps.

Performances de HashSet

HashSet étend la classe Abstract Set et implémente Ensemble , Clonable , et Sérialisable interfaces où E est le type d’éléments maintenus par cet ensemble. La sous-classe directement connue de HashSet est LinkedHashSet .

Désormais, pour maintenir des performances en temps constant, l'itération sur HashSet nécessite un temps proportionnel à la somme de la taille de l'instance HashSet (le nombre d'éléments) plus la capacité de l'instance HashMap de sauvegarde (le nombre de compartiments). Il est donc très important de ne pas définir une capacité initiale trop élevée (ou un facteur de charge trop faible) si les performances itératives sont importantes.

  • Capacité initiale : La capacité initiale signifie le nombre de compartiments lorsque la table de hachage (HashSet utilise en interne la structure de données de la table de hachage) est créée. Le nombre de compartiments sera automatiquement augmenté si la taille actuelle est pleine.
  • Facteur de charge: Le facteur de charge est une mesure du niveau de remplissage autorisé du HashSet avant que sa capacité ne soit automatiquement augmentée. Lorsque le nombre d'entrées dans la table de hachage dépasse le produit du facteur de charge et de la capacité actuelle, la table de hachage est rehachée (c'est-à-dire que les structures de données internes sont reconstruites) de sorte que la table de hachage contienne environ deux fois le nombre de compartiments.
 Number of stored elements in the table Load Factor = ----------------------------------------- Size of the hash table>

Exemple: Si la capacité interne est de 16 et le facteur de charge est de 0,75, le nombre de compartiments sera automatiquement augmenté lorsque la table contient 12 éléments.

Effet sur les performances :

Le facteur de charge et la capacité initiale sont deux facteurs principaux qui affectent les performances des opérations HashSet. Un facteur de charge de 0,75 offre des performances très efficaces en termes de complexité temporelle et spatiale. Si nous augmentons la valeur du facteur de charge plus que cela, la surcharge de mémoire sera réduite (car cela diminuera l'opération de reconstruction interne), mais cela affectera l'opération d'ajout et de recherche dans la table de hachage. Pour réduire l'opération de remaniement, nous devons choisir judicieusement la capacité initiale. Si la capacité initiale est supérieure au nombre maximum d'entrées divisé par le facteur de charge, aucune opération de répétition n'aura lieu.

Note: L'implémentation dans un HashSet n'est pas synchronisée, dans le sens où si plusieurs threads accèdent simultanément à un ensemble de hachage et qu'au moins un des threads modifie l'ensemble, il doit être synchronisé en externe. Ceci est généralement accompli en synchronisant sur un objet qui encapsule naturellement l'ensemble. Si aucun objet de ce type n’existe, l’ensemble doit être encapsulé à l’aide de la méthode Collections.synchronizedSet. Il est préférable de le faire au moment de la création, pour éviter tout accès accidentel non synchronisé à l'ensemble, comme indiqué ci-dessous :

Set s = Collections.synchronizedSet(new HashSet(…));

Méthodes utilisées avec HashSet

1. Méthodes héritées de la classe java.util.AbstractSet

Méthode

Description

équivaut à() Utilisé pour vérifier l'égalité d'un Object avec un HashSet et les comparer. La liste renvoie true uniquement si les deux HashSet contiennent les mêmes éléments, quel que soit leur ordre.
code de hachage() Renvoie la valeur du code de hachage pour cet ensemble.
supprimerTout(collection) Cette méthode permet de supprimer tous les éléments de la collection qui sont présents dans l'ensemble. Cette méthode renvoie true si cet ensemble change à la suite de l'appel.

2. Méthodes héritées de la classe java.util.AbstractCollection

MÉTHODE

DESCRIPTION

ajouterTout(collection)

Cette méthode est utilisée pour ajouter tous les éléments de la collection mentionnée à l'ensemble existant.

Les éléments sont ajoutés aléatoirement sans suivre aucun ordre précis.

contientTout(collection)

Cette méthode permet de vérifier si l'ensemble contient ou non tous les éléments présents dans la collection donnée.

Cette méthode renvoie vrai si l'ensemble contient tous les éléments et renvoie faux si l'un des éléments est manquant.

retenirTout(collection) Cette méthode est utilisée pour conserver tous les éléments de l'ensemble qui sont mentionnés dans la collection donnée. Cette méthode renvoie true si cet ensemble a changé à la suite de l'appel.
versArray() Cette méthode est utilisée pour former un tableau des mêmes éléments que celui du Set.
àChaîne() La méthode toString() de Java HashSet est utilisée pour renvoyer une représentation sous forme de chaîne des éléments de la collection HashSet.

3. Méthodes déclarées dans l'interface java.util.Collection

MÉTHODE

DESCRIPTION

parallèleStream() Renvoie un Stream éventuellement parallèle avec cette collection comme source.
RemoveIf? (Filtre de prédicat) Supprime tous les éléments de cette collection qui satisfont au prédicat donné.
flux() Renvoie un Stream séquentiel avec cette collection comme source.
toArray? (générateur de IntFunction) Renvoie un tableau contenant tous les éléments de cette collection, en utilisant la fonction génératrice fournie pour allouer le tableau renvoyé.

4. Méthodes déclarées dans l'interface java.lang.Iterable

MÉTHODE

DESCRIPTION

forEach ? (Action du consommateur) Exécute l'action donnée pour chaque élément de l'Iterable jusqu'à ce que tous les éléments aient été traités ou que l'action lève une exception.

5. Méthodes déclarées dans l'interface java.util.Set

MÉTHODE

DESCRIPTION

ajouterTout ?(Collection c) Ajoute tous les éléments de la collection spécifiée à cet ensemble s'ils ne sont pas déjà présents (opération facultative).
contientTout ?(Collection c) Renvoie vrai si cet ensemble contient tous les éléments de la collection spécifiée.
est égal ?(Objet o) Compare l'objet spécifié avec cet ensemble pour l'égalité.
code de hachage() Renvoie la valeur du code de hachage pour cet ensemble.
supprimerTout ?(Collection c) Supprime de cet ensemble tous ses éléments contenus dans la collection spécifiée (opération facultative).
retenirTout ?(Collection c) Conserve uniquement les éléments de cet ensemble qui sont contenus dans la collection spécifiée (opération facultative).
versArray() Renvoie un tableau contenant tous les éléments de cet ensemble.
versArray?(T[] a) Renvoie un tableau contenant tous les éléments de cet ensemble ; le type d'exécution du tableau renvoyé est celui du tableau spécifié.

FAQ sur HashSet en Java

T1. Qu’est-ce que HashSet en Java ?

Répondre:

HashSet est un type de classe qui étend AbstractSet et implémente les interfaces Set.

Q2. Pourquoi HashSet est-il utilisé ?

Répondre:

HashSet est utilisé pour éviter les données en double et pour trouver de la valeur avec la méthode rapide.

Q3. Différences entre HashSet et HashMap.

Répondre:

Base

Jeu de hachage

Carte de hachage

Mise en œuvre HashSet implémente une interface Set. HashMap implémente une interface storesMap.
Doublons HashSet n'autorise pas les valeurs en double. HashMap stocke les paires clé et valeur et n'autorise pas les clés en double. Si la clé est en double, l'ancienne clé est remplacée par la nouvelle valeur.
Nombre d'objets pendant le stockage des objets HashSet ne nécessite qu'un seul ajout d'objet (Object o). HashMap nécessite deux objets put (clé K, valeur V) pour ajouter un élément à l'objet HashMap.
Valeur factice HashSet utilise en interne HashMap pour ajouter des éléments. Dans HashSet, l'argument passé dans la méthode add(Object) sert de clé K. Java associe en interne une valeur factice pour chaque valeur passée dans la méthode add(Object). HashMap n'a aucun concept de valeur factice.
Stockage ou ajout d'un mécanisme HashSet utilise en interne l'objet HashMap pour stocker ou ajouter les objets. HashMap utilise en interne le hachage pour stocker ou ajouter des objets
Plus rapide HashSet est plus lent que HashMap. HashMap est plus rapide que HashSet.
Insertion HashSet utilise la méthode add() pour ajouter ou stocker des données. HashMap utilise la méthode put() pour stocker les données.
Exemple HashSet est un ensemble, par ex. {1, 2, 3, 4, 5, 6, 7}. HashMap est une carte clé -> paire de valeurs (clé à valeur), par ex. {a -> 1, b -> 2, c -> 2, d -> 1}.

Q4. Différences entre HashSet et TreeSet en Java.

Répondre:

Base

Jeu de hachage

Ensemble d'arbres

stlc
Vitesse et mise en œuvre interne de l'action de lancer Pour les opérations telles que la recherche, l'insertion et la suppression. Ces opérations prennent en moyenne un temps constant. HashSet est plus rapide que TreeSet. HashSet est implémenté à l'aide d'une table de hachage. TreeSet prend O (Log n) pour la recherche, l'insertion et la suppression, ce qui est supérieur à HashSet. Mais TreeSet conserve les données triées. En outre, il prend en charge des opérations telles que upper() (renvoie l'élément le moins supérieur), floor(), plafond(), etc. Ces opérations sont également O(Log n) dans TreeSet et ne sont pas prises en charge dans HashSet. TreeSet est implémenté à l'aide d'un arbre de recherche binaire à équilibrage automatique (arbre rouge-noir). TreeSet est soutenu par TreeMap en Java.
Commande Les éléments de HashSet ne sont pas ordonnés. TreeSet conserve les objets dans l'ordre trié défini par la méthode Comparable ou Comparator en Java. Les éléments TreeSet sont triés par ordre croissant par défaut. Il propose plusieurs méthodes pour gérer l'ensemble ordonné comme first(), last(), headSet(), tailSet(), etc.
Objet nul HashSet autorise l'objet nul. TreeSet n'autorise pas les objets nuls et lance NullPointerException, pourquoi, parce que TreeSet utilise la méthode compareTo() pour comparer les clés, et compareTo() lancera java.lang.NullPointerException.
Comparaison HashSet utilise la méthode equals() pour comparer deux objets dans le Set et pour détecter les doublons. TreeSet utilise la méthode compareTo() dans le même but. Si equals() et compareTo() ne sont pas cohérents, c'est-à-dire que pour deux objets égaux, equals doit renvoyer true tandis que compareTo() doit renvoyer zéro, alors cela rompra le contrat de l'interface Set et autorisera les doublons dans les implémentations Set comme TreeSet