Java-hashset class implementeert de Set-interface, ondersteund door een hashtabel die eigenlijk een HashMap-instantie is. Er wordt geen garantie gegeven met betrekking tot de iteratievolgorde van de hashsets, wat betekent dat de klasse de constante volgorde van elementen in de loop van de tijd niet garandeert. Deze klasse staat het null-element toe. De klasse biedt ook constante tijdprestaties voor de basisbewerkingen zoals toevoegen, verwijderen, bevat en grootte, ervan uitgaande dat de hashfunctie de elementen op de juiste manier over de buckets verspreidt, wat we verderop in het artikel zullen zien.
Java HashSet-functies
Hieronder worden enkele belangrijke kenmerken van HashSet vermeld:
- Implementeert Interface instellen .
- De onderliggende datastructuur voor HashSet is Hashtabel .
- Omdat het de Set Interface implementeert, zijn dubbele waarden niet toegestaan.
- Het is niet gegarandeerd dat objecten die u in HashSet invoegt, in dezelfde volgorde worden ingevoegd. Objecten worden ingevoegd op basis van hun hashcode.
- NULL-elementen zijn toegestaan in HashSet.
- HashSet implementeert ook Serialiseerbaar En Kloonbaar interfaces.
Verklaring van HashSet
public class HashSet extends AbstractSet implements Set, Cloneable, Serializable>
waar EN is het type elementen dat is opgeslagen in een HashSet.
HashSet Java-voorbeeld
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());> >}> }> |
geheel getal dubbele java
>
>Uitgang:
1>
Voordat een object wordt opgeslagen, controleert HashSet of er een bestaand item is met behulp van de methoden hashCode() en equals(). In het bovenstaande voorbeeld worden twee lijsten als gelijkwaardig beschouwd als ze dezelfde elementen in dezelfde volgorde hebben. Wanneer u een beroep doet op de hashCode() methode op de twee lijsten, zouden ze allebei dezelfde hash opleveren omdat ze gelijk zijn.
Opmerking: HashSet wel geen dubbele items opslaan , als je twee objecten geeft die gelijk zijn, wordt alleen de eerste opgeslagen, hier is het lijst1.
De hiërarchie van HashSet is als volgt:
Interne werking van een HashSet
Alle klassen van de Set-interface worden intern ondersteund door Map. HashSet gebruikt HashMap om zijn object intern op te slaan. Je vraagt je vast af dat we, om een waarde in HashMap in te voeren, een sleutel-waardepaar nodig hebben, maar in HashSet geven we slechts één waarde door.
Opslag in HashMap: Eigenlijk fungeert de waarde die we in HashSet invoegen als een sleutel tot het kaartobject en voor zijn waarde gebruikt Java een constante variabele. In het sleutel-waardepaar zijn dus alle waarden hetzelfde.
Implementatie van HashSet in Java-doc
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();> Als we kijken naar de toevoegen() methode van de HashSet-klasse:
public boolean add(E e) { return map.put(e, PRESENT) == null; }> We kunnen opmerken dat de methode add() van de klasse HashSet intern de neerzetten() methode om het HashMap-object te ondersteunen door het element dat u hebt opgegeven als sleutel en constante PRESENT als waarde door te geven. verwijderen() methode werkt ook op dezelfde manier. Het roept intern de verwijdermethode van de kaartinterface aan.
public boolean remove(Object o) { return map.remove(o) == PRESENT; }> HashSet slaat niet alleen unieke objecten op, maar ook een unieke verzameling objecten leuk vinden ArrayLijst , GelinkteLijst , Vector,..etc.
Constructeurs van de HashSet-klasse
Om een HashSet te maken, moeten we een object van de klasse HashSet maken. De klasse HashSet bestaat uit verschillende constructors die de mogelijke creatie van de HashSet mogelijk maken. Hieronder volgen de constructors die beschikbaar zijn in deze klasse.
1. HashSet()
Deze constructor wordt gebruikt om een leeg HashSet-object te bouwen waarin de standaard initiële capaciteit 16 is en de standaard belastingsfactor 0,75 is. Als we een lege HashSet willen maken met de naam hs, kan deze worden gemaakt als:
HashSet hs = new HashSet();>
2. HashSet (int initiële capaciteit)
Deze constructor wordt gebruikt om een leeg HashSet-object te bouwen waarin de initialCapacity is opgegeven op het moment dat het object wordt gemaakt. Hier blijft de standaard loadFactor 0,75.
HashSet hs = new HashSet(int initialCapacity);>
3. HashSet (int initiële capaciteit, float loadFactor)
Deze constructor wordt gebruikt om een leeg HashSet-object te bouwen waarin de initialCapacity en loadFactor zijn opgegeven op het moment dat het object wordt gemaakt.
HashSet hs = new HashSet(int initialCapacity, float loadFactor);>
4. HashSet (verzameling)
Deze constructor wordt gebruikt om een HashSet-object te bouwen dat alle elementen uit de gegeven verzameling bevat. Kortom, deze constructor wordt gebruikt wanneer er een conversie nodig is van een Collection-object naar het HashSet-object. Als we een HashSet willen maken met de naam hs, kan deze worden gemaakt als:
HashSet hs = new HashSet(Collection C);>
Hieronder vindt u de implementatie van de bovenstaande onderwerpen:
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());> >}> }> |
>
>Uitgang:
[South Africa, Australia, India] List contains India or not:true List after removing Australia:[South Africa, India] Iterating over list: South Africa India>
Methoden in HashSet
| METHODE | BESCHRIJVING |
|---|---|
| toevoegen(En en) | Wordt gebruikt om het opgegeven element toe te voegen als het niet aanwezig is. Als het wel aanwezig is, wordt false geretourneerd. |
| duidelijk() | Wordt gebruikt om alle elementen uit de set te verwijderen. |
| bevat(Object o) | Wordt gebruikt om waar te retourneren als een element aanwezig is in een set. |
| verwijder(Object o) | Wordt gebruikt om het element te verwijderen als het aanwezig is in de set. |
| iterator() | Wordt gebruikt om een iterator over het element in de set te retourneren. |
| is leeg() | Wordt gebruikt om te controleren of de set leeg is of niet. Retourneert waar voor leeg en onwaar voor een niet-lege voorwaarde voor set. |
| maat() | Wordt gebruikt om de grootte van de set terug te geven. |
| kloon() | Wordt gebruikt om een ondiepe kopie van de set te maken. |
Verschillende bewerkingen uitvoeren op HashSet
Laten we eens kijken hoe we een paar veelgebruikte bewerkingen op de HashSet kunnen uitvoeren.
1. Elementen toevoegen aan HashSet
Om een element aan de HashSet toe te voegen, kunnen we de add() methode gebruiken. De invoegopdracht wordt echter niet bewaard in de HashSet. We moeten er rekening mee houden dat dubbele elementen niet zijn toegestaan en dat alle dubbele elementen worden genegeerd.
Voorbeeld
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);> >}> }> |
>
>Uitgang:
HashSet elements : [Geek, For, Geeks]>
2. Elementen verwijderen in HashSet
De waarden kunnen uit de HashSet worden verwijderd met behulp van de remove() -methode.
Voorbeeld
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'>));> >}> }> |
>
>Uitgang:
Initial HashSet [A, B, Geek, For, Geeks, Z] After removing element [A, Geek, For, Geeks, Z] Element AC exists in the Set : false>
3. Itereren via de HashSet
Doorloop de elementen van HashSet met behulp van de iterator() -methode. De meest bekende is ook het gebruik van de verbeterd voor lus.
Voorbeeld
Codeblok
UitvoerA, B, Geek, For, Geeks, Z, A, B, Geek, For, Geeks, Z,>
Tijdcomplexiteit van HashSet-bewerkingen: De onderliggende gegevensstructuur voor HashSet is hashtabel. Dus schrijf de tijdcomplexiteit (gemiddeld of gebruikelijk) af voor het toevoegen, verwijderen en opzoeken (bevat de methode) van de HashSet-bewerkingen O(1) tijd.
Prestaties van HashSet
HashSet breidt de Abstract Set-klasse uit en implementeert Set , Kloonbaar , en Serialiseerbaar interfaces waarbij E het type elementen is dat door deze set wordt onderhouden. De direct bekende subklasse van HashSet is LinkedHashSet .
Voor het behoud van constante tijdprestaties vereist het herhalen van HashSet tijd die evenredig is aan de som van de grootte van de HashSet-instantie (het aantal elementen) plus de capaciteit van de ondersteunende HashMap-instantie (het aantal buckets). Het is dus erg belangrijk om de initiële capaciteit niet te hoog in te stellen (of de belastingsfactor te laag) als iteratieprestaties belangrijk zijn.
- Initiële capaciteit: De initiële capaciteit betekent het aantal buckets wanneer de hashtabel (HashSet gebruikt intern de hashtabelgegevensstructuur) wordt gemaakt. Het aantal emmers wordt automatisch verhoogd als de huidige grootte vol raakt.
- Ladingsfactor: De bezettingsgraad is een maatstaf voor hoe vol de HashSet mag worden voordat de capaciteit automatisch wordt verhoogd. Wanneer het aantal vermeldingen in de hashtabel het product van de belastingsfactor en de huidige capaciteit overschrijdt, wordt de hashtabel opnieuw gehasht (dat wil zeggen dat de interne datastructuren opnieuw worden opgebouwd), zodat de hashtabel ongeveer tweemaal het aantal buckets heeft.
Number of stored elements in the table Load Factor = ----------------------------------------- Size of the hash table>
Voorbeeld: Als de interne capaciteit 16 is en de bezettingsgraad 0,75 is, wordt het aantal emmers automatisch verhoogd als de tafel 12 elementen bevat.
Effect op prestaties:
Belastingsfactor en initiële capaciteit zijn twee belangrijke factoren die de prestaties van HashSet-bewerkingen beïnvloeden. Een belastingsfactor van 0,75 levert zeer effectieve prestaties met betrekking tot tijd- en ruimtecomplexiteit. Als we de belastingsfactorwaarde meer dan dat verhogen, wordt de geheugenoverhead verminderd (omdat dit de interne herbouwbewerking zal verminderen), maar dit heeft invloed op de toevoeg- en zoekbewerking in de hashtabel. Om de herhashing-operatie te verminderen, moeten we de initiële capaciteit verstandig kiezen. Als de initiële capaciteit groter is dan het maximale aantal vermeldingen gedeeld door de bezettingsgraad, zal er nooit een herhash-bewerking plaatsvinden.
Opmerking: De implementatie in een HashSet is niet gesynchroniseerd, in die zin dat als meerdere threads tegelijkertijd toegang hebben tot een hashset en ten minste één van de threads de set wijzigt, deze extern moet worden gesynchroniseerd. Dit wordt doorgaans bereikt door te synchroniseren op een object dat op natuurlijke wijze de set inkapselt. Als een dergelijk object niet bestaat, moet de set worden ingepakt met behulp van de Collections.synchronizedSet-methode. Dit kunt u het beste doen tijdens het maken van de set, om onbedoelde, niet-gesynchroniseerde toegang tot de set te voorkomen, zoals hieronder weergegeven:
Stel s = Collections.synchronizedSet(nieuwe HashSet(…));
Methoden gebruikt met HashSet
1. Methoden overgenomen van klasse java.util.AbstractSet
| Methode | Beschrijving binaire boom java |
|---|---|
| is gelijk aan() | Wordt gebruikt om de gelijkheid van een object met een HashSet te verifiëren en deze te vergelijken. De lijst retourneert alleen waar als beide HashSets dezelfde elementen bevatten, ongeacht de volgorde. |
| hashcode() | Retourneert de hashcodewaarde voor deze set. |
| verwijderAlles(verzameling) | Deze methode wordt gebruikt om alle elementen uit de collectie te verwijderen die in de set aanwezig zijn. Deze methode retourneert true als deze set verandert als gevolg van de aanroep. |
2. Methoden overgenomen van klasse java.util.AbstractCollection
| METHODE | BESCHRIJVING |
|---|---|
| addAll(verzameling) | Deze methode wordt gebruikt om alle elementen uit de genoemde collectie aan de bestaande set toe te voegen. De elementen worden willekeurig toegevoegd zonder een specifieke volgorde te volgen. |
| bevatAlles(verzameling) | Deze methode wordt gebruikt om te controleren of de set alle elementen bevat die aanwezig zijn in de gegeven collectie of niet. Deze methode retourneert true als de set alle elementen bevat en false als een van de elementen ontbreekt. |
| behoudenAlles(verzameling) | Deze methode wordt gebruikt om alle elementen uit de set te behouden die in de betreffende collectie worden vermeld. Deze methode retourneert true als deze set is gewijzigd als gevolg van de aanroep. |
| toArray() | Deze methode wordt gebruikt om een array te vormen van dezelfde elementen als die van de Set. |
| toString() | De toString()-methode van Java HashSet wordt gebruikt om een tekenreeksrepresentatie van de elementen van de HashSet-collectie terug te geven. |
3. Methoden gedeclareerd in interface java.util.Collection
| METHODE | BESCHRIJVING |
|---|---|
| parallelStream() | Retourneert een mogelijk parallelle stream met deze verzameling als bron. |
| removeIf?(Predikaatfilter) | Verwijdert alle elementen van deze verzameling die aan het gegeven predikaat voldoen. |
| stroom() | Retourneert een sequentiële stream met deze verzameling als bron. |
| toArray?(IntFunction-generator) | Retourneert een array die alle elementen in deze verzameling bevat, waarbij de meegeleverde generatorfunctie wordt gebruikt om de geretourneerde array toe te wijzen. |
4. Methoden gedeclareerd in interface java.lang.Iterable
| METHODE | BESCHRIJVING |
|---|---|
| voorElk?(Consumentenactie) | Voert de gegeven actie uit voor elk element van de iterabele totdat alle elementen zijn verwerkt of de actie een uitzondering genereert. |
5. Methoden gedeclareerd in interface java.util.Set
| METHODE | BESCHRIJVING |
|---|---|
| alles toevoegen?(Verzameling c) | Voegt alle elementen in de opgegeven verzameling toe aan deze set als ze nog niet aanwezig zijn (optionele bewerking). |
| bevatAlles?(Verzameling c) | Retourneert waar als deze set alle elementen van de opgegeven verzameling bevat. |
| gelijk aan? (Object o) | Vergelijkt het opgegeven object met deze set op gelijkheid. |
| hashCode() | Retourneert de hashcodewaarde voor deze set. |
| alles verwijderen? (Verzameling c) | Verwijdert uit deze set alle elementen die zich in de opgegeven verzameling bevinden (optionele bewerking). |
| alles behouden? (Verzameling c) | Bewaart alleen de elementen in deze set die deel uitmaken van de opgegeven verzameling (optionele bewerking). |
| toArray() | Retourneert een array die alle elementen in deze set bevat. |
| toArray?(T[] a) | Geeft een array terug die alle elementen in deze set bevat; het runtimetype van de geretourneerde array is dat van de opgegeven array. |
Veelgestelde vragen in HashSet in Java
Q1. Wat is HashSet in Java?
Antwoord:
HashSet is een type klasse dat AbstractSet uitbreidt en Set-interfaces implementeert.
Vraag 2. Waarom wordt HashSet gebruikt?
Antwoord:
HashSet wordt gebruikt om dubbele gegevens te vermijden en om waarde te vinden met de snelle methode.
Q3. Verschillen tussen HashSet en HashMap.
Antwoord:
| Basis | HashSet | Hash kaart |
|---|---|---|
| Implementatie | HashSet implementeert een Set-interface. | HashMap implementeert een storeMap-interface. |
| Duplicaten | HashSet staat geen dubbele waarden toe. | HashMap slaat de sleutel- en waardeparen op en staat geen dubbele sleutels toe. Als de sleutel duplicaat is, wordt de oude sleutel vervangen door de nieuwe waarde. |
| Aantal objecten tijdens het opslaan van objecten | HashSet vereist slechts één objecttoevoeging (Object o). | HashMap vereist twee put-objecten (K-sleutel, V-waarde) om een element aan het HashMap-object toe te voegen. |
| Dummy-waarde | HashSet gebruikt intern HashMap om elementen toe te voegen. In HashSet fungeert het argument dat wordt doorgegeven in de add(Object)-methode als sleutel K. Java associeert intern een dummywaarde voor elke waarde die wordt doorgegeven in de add(Object)-methode. | HashMap kent geen enkel concept van dummywaarde. |
| Een mechanisme opslaan of toevoegen | HashSet gebruikt intern het HashMap-object om de objecten op te slaan of toe te voegen. | HashMap gebruikt intern hashing om objecten op te slaan of toe te voegen |
| Sneller | HashSet is langzamer dan HashMap. | HashMap is sneller dan HashSet. |
| Plaatsing | HashSet gebruikt de add()-methode voor het toevoegen of opslaan van gegevens. | HashMap gebruikt de put()-methode voor het opslaan van gegevens. |
| Voorbeeld | HashSet is een set, b.v. {1, 2, 3, 4, 5, 6, 7}. | HashMap is een sleutel -> waardepaar (sleutel tot waarde) kaart, b.v. {a -> 1, b -> 2, c -> 2, d -> 1}. |
Q4. Verschillen tussen HashSet en TreeSet in Java.
Antwoord:
| Basis | HashSet | BoomSet |
|---|---|---|
| Snelheid en interne uitvoering van de werpactie | Voor bewerkingen zoals zoeken, invoegen en verwijderen. Het kost gemiddeld een constante tijd voor deze bewerkingen. HashSet is sneller dan TreeSet. HashSet wordt geïmplementeerd met behulp van een hashtabel. | TreeSet gebruikt O(Log n) voor zoeken, invoegen en verwijderen, wat hoger is dan HashSet. Maar TreeSet bewaart gesorteerde gegevens. Het ondersteunt ook bewerkingen zoals hoger() (retourneert het minst hogere element), vloer(), plafond(), etc. Deze bewerkingen zijn ook O(Log n) in TreeSet en worden niet ondersteund in HashSet. TreeSet wordt geïmplementeerd met behulp van een zelfbalancerende binaire zoekboom (rood-zwarte boom). TreeSet wordt ondersteund door TreeMap in Java. |
| Bestellen | Elementen in HashSet zijn niet geordend. | TreeSet onderhoudt objecten in gesorteerde volgorde, gedefinieerd door de Comparable- of Comparator-methode in Java. TreeSet-elementen worden standaard in oplopende volgorde gesorteerd. Het biedt verschillende methoden om met de geordende set om te gaan, zoals first(), last(), headSet(), tailSet(), enz. |
| Nul-object | HashSet staat het null-object toe. | TreeSet staat geen null-object toe en genereert NullPointerException. Dit komt omdat TreeSet de methode CompareTo() gebruikt om sleutels te vergelijken, en CompareTo() java.lang.NullPointerException genereert. |
| Vergelijking | HashSet gebruikt de methode equals() om twee objecten in de set te vergelijken en om duplicaten te detecteren. | TreeSet gebruikt de methode CompareTo() voor hetzelfde doel. Als equals() en CompareTo() niet consistent zijn, d.w.z. voor twee gelijke objecten moet equals true retourneren terwijl CompareTo() nul zou moeten retourneren, dan zal dit het contract van de Set-interface verbreken en duplicaten toestaan in Set-implementaties zoals TreeSet |