logo

HashSet in Java

Java HashSet Die Klasse implementiert die Set-Schnittstelle, unterstützt durch eine Hash-Tabelle, die eigentlich eine HashMap-Instanz ist. Es wird keine Garantie für die Iterationsreihenfolge der Hash-Sets übernommen, was bedeutet, dass die Klasse nicht die konstante Reihenfolge der Elemente über die Zeit garantiert. Diese Klasse lässt das Nullelement zu. Die Klasse bietet auch eine konstante Zeitleistung für die Grundoperationen wie Hinzufügen, Entfernen, Enthält und Größe, vorausgesetzt, die Hash-Funktion verteilt die Elemente ordnungsgemäß auf die Buckets, was wir weiter unten im Artikel sehen werden.

Java HashSet-Funktionen

Nachfolgend sind einige wichtige Funktionen von HashSet aufgeführt:

  • Implementiert Schnittstelle festlegen .
  • Die zugrunde liegende Datenstruktur für HashSet ist Hash-tabelle .
  • Da es die Set-Schnittstelle implementiert, sind doppelte Werte nicht zulässig.
  • Es kann nicht garantiert werden, dass Objekte, die Sie in HashSet einfügen, in derselben Reihenfolge eingefügt werden. Objekte werden basierend auf ihrem Hash-Code eingefügt.
  • NULL-Elemente sind in HashSet zulässig.
  • HashSet implementiert auch Serialisierbar Und Klonbar Schnittstellen.

Deklaration von HashSet

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

Wo UND ist der Typ der in einem HashSet gespeicherten Elemente.



HashSet-Java-Beispiel

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());> >}> }>

Java, wie man einen String in int konvertiert
>

>

Ausgabe:

1>

Vor dem Speichern eines Objekts prüft HashSet mithilfe der Methoden hashCode() und equal(), ob ein Eintrag vorhanden ist. Im obigen Beispiel gelten zwei Listen als gleich, wenn sie dieselben Elemente in derselben Reihenfolge enthalten. Wenn Sie die aufrufen Hash-Code() Wenn Sie die Methode auf die beiden Listen anwenden, würden beide den gleichen Hash liefern, da sie gleich sind.

Notiz: HashSet tut es Speichern Sie keine doppelten Elemente Wenn Sie zwei Objekte angeben, die gleich sind, wird nur das erste gespeichert, hier ist es list1.

Die Hierarchie von HashSet ist wie folgt:

Interne Funktionsweise eines HashSets

Alle Klassen der Set-Schnittstelle werden intern von Map gesichert. HashSet verwendet HashMap zum internen Speichern seines Objekts. Sie fragen sich bestimmt, dass wir zum Eingeben eines Werts in HashMap ein Schlüssel-Wert-Paar benötigen, in HashSet jedoch nur einen Wert übergeben.

Speicherung in HashMap: Tatsächlich fungiert der Wert, den wir in HashSet einfügen, als Schlüssel zum Kartenobjekt und für seinen Wert verwendet Java eine konstante Variable. Im Schlüssel-Wert-Paar sind also alle Werte gleich.

Implementierung von HashSet im Java-Dokument

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();>

Wenn wir uns das ansehen hinzufügen() Methode der HashSet-Klasse:

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

Wir können feststellen, dass die Methode add() der Klasse HashSet intern die aufruft setzen() Methode zur Sicherung des HashMap-Objekts durch Übergabe des von Ihnen angegebenen Elements als Schlüssel und der Konstante PRESENT als Wert. entfernen() Methode funktioniert auch auf die gleiche Weise. Es ruft intern die Methode „remove“ der Map-Schnittstelle auf.

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

HashSet speichert nicht nur einzigartige Objekte, sondern auch eine einzigartige Sammlung von Objekten wie Anordnungsliste , LinkedList , Vektor usw.

Konstruktoren der HashSet-Klasse

Um ein HashSet zu erstellen, müssen wir ein Objekt der HashSet-Klasse erstellen. Die HashSet-Klasse besteht aus verschiedenen Konstruktoren, die die mögliche Erstellung des HashSets ermöglichen. Im Folgenden sind die in dieser Klasse verfügbaren Konstruktoren aufgeführt.

1. HashSet()

Mit diesem Konstruktor wird ein leeres HashSet-Objekt erstellt, dessen standardmäßige Anfangskapazität 16 und der standardmäßige Auslastungsfaktor 0,75 beträgt. Wenn wir ein leeres HashSet mit dem Namen hs erstellen möchten, kann es wie folgt erstellt werden:

HashSet hs = new HashSet();>

2. HashSet(int initialCapacity)

Mit diesem Konstruktor wird ein leeres HashSet-Objekt erstellt, in dem die initialCapacity zum Zeitpunkt der Objekterstellung angegeben wird. Hier bleibt der Standard-LoadFactor 0,75.

HashSet hs = new HashSet(int initialCapacity);>

3. HashSet(int initialCapacity, float loadFactor)

Mit diesem Konstruktor wird ein leeres HashSet-Objekt erstellt, in dem initialCapacity und LoadFactor zum Zeitpunkt der Objekterstellung angegeben werden.

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

4. HashSet(Sammlung)

Dieser Konstruktor wird verwendet, um ein HashSet-Objekt zu erstellen, das alle Elemente aus der angegebenen Sammlung enthält. Kurz gesagt, dieser Konstruktor wird verwendet, wenn eine Konvertierung von einem Collection-Objekt in das HashSet-Objekt erforderlich ist. Wenn wir ein HashSet mit dem Namen hs erstellen möchten, kann es wie folgt erstellt werden:

HashSet hs = new HashSet(Collection C);>

Nachfolgend finden Sie die Umsetzung der oben genannten Themen:

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());> >}> }>

>

>

Ausgabe:

[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

BESCHREIBUNG

hinzufügen(Und und) Wird verwendet, um das angegebene Element hinzuzufügen, wenn es nicht vorhanden ist. Wenn es vorhanden ist, wird „false“ zurückgegeben.
klar() Wird verwendet, um alle Elemente aus der Menge zu entfernen.
enthält(Objekt o) Wird verwendet, um „true“ zurückzugeben, wenn ein Element in einer Menge vorhanden ist.
entfernen(Objekt o) Wird verwendet, um das Element zu entfernen, wenn es in der Menge vorhanden ist.
Iterator() Wird verwendet, um einen Iterator über das Element in der Menge zurückzugeben.
ist leer() Wird verwendet, um zu prüfen, ob die Menge leer ist oder nicht. Gibt „true“ für eine leere und „false“ für eine nicht leere Bedingung für set zurück.
Größe() Wird verwendet, um die Größe des Satzes zurückzugeben.
Klon() Wird verwendet, um eine flache Kopie des Sets zu erstellen.

Durchführen verschiedener Vorgänge an HashSet

Sehen wir uns an, wie man einige häufig verwendete Vorgänge am HashSet durchführt.

1. Elemente in HashSet hinzufügen

Um dem HashSet ein Element hinzuzufügen, können wir die Methode add() verwenden. Allerdings bleibt die Einfügereihenfolge im HashSet nicht erhalten. Wir müssen beachten, dass doppelte Elemente nicht zulässig sind und alle doppelten Elemente ignoriert werden.

Beispiel

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);> >}> }>

>

>

Ausgabe:

HashSet elements : [Geek, For, Geeks]>

2. Elemente in HashSet entfernen

Die Werte können mit der Methode „remove()“ aus dem HashSet entfernt werden.

Beispiel

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'>));> >}> }>

>

>

Ausgabe:

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

3. Iterieren durch das HashSet

Durchlaufen Sie die Elemente von HashSet mit der Methode iterator(). Die bekannteste davon ist auch die Verwendung von erweiterte for-Schleife.

Beispiel

Codeblock

Ausgabe

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

Zeitkomplexität von HashSet-Operationen: Die zugrunde liegende Datenstruktur für HashSet ist hashtable. Amortisieren Sie also (durchschnittlich oder im Normalfall) die Zeit, die für den Vorgang des Hinzufügens, Entfernens und Suchens (enthält Methode) von HashSet benötigt wird O(1) Zeit.

Leistung von HashSet

HashSet erweitert die Abstract-Set-Klasse und implementiert Satz , Klonbar , und Serialisierbar Schnittstellen, wobei E der Typ der von dieser Menge verwalteten Elemente ist. Die direkt bekannte Unterklasse von HashSet ist LinkedHashSet.

Um nun eine konstante Zeitleistung aufrechtzuerhalten, erfordert die Iteration über HashSet Zeit, die proportional zur Summe der Größe der HashSet-Instanz (der Anzahl der Elemente) plus der Kapazität der unterstützenden HashMap-Instanz (der Anzahl der Buckets) ist. Daher ist es sehr wichtig, die Anfangskapazität nicht zu hoch (oder den Auslastungsfaktor zu niedrig) festzulegen, wenn die Iterationsleistung wichtig ist.

  • Anfangskapazität: Die anfängliche Kapazität bezeichnet die Anzahl der Buckets, wenn die Hashtabelle (HashSet verwendet intern die Hashtabellen-Datenstruktur) erstellt wird. Die Anzahl der Buckets wird automatisch erhöht, wenn die aktuelle Größe voll wird.
  • Ladefaktor: Der Ladefaktor ist ein Maß dafür, wie voll das HashSet werden darf, bevor seine Kapazität automatisch erhöht wird. Wenn die Anzahl der Einträge in der Hash-Tabelle das Produkt aus Auslastungsfaktor und aktueller Kapazität übersteigt, wird die Hash-Tabelle erneut gehasht (d. h. die internen Datenstrukturen werden neu erstellt), sodass die Hash-Tabelle ungefähr die doppelte Anzahl an Buckets aufweist.
 Number of stored elements in the table Load Factor = ----------------------------------------- Size of the hash table>

Beispiel: Wenn die interne Kapazität 16 beträgt und der Auslastungsfaktor 0,75 beträgt, wird die Anzahl der Buckets automatisch erhöht, wenn die Tabelle 12 Elemente enthält.

Auswirkung auf die Leistung:

Auslastungsfaktor und Anfangskapazität sind zwei Hauptfaktoren, die die Leistung von HashSet-Vorgängen beeinflussen. Ein Lastfaktor von 0,75 bietet eine sehr effektive Leistung hinsichtlich der zeitlichen und räumlichen Komplexität. Wenn wir den Lastfaktorwert weiter erhöhen, wird der Speicheraufwand reduziert (da dadurch der interne Wiederherstellungsvorgang verringert wird), es wirkt sich jedoch auf den Hinzufügungs- und Suchvorgang in der Hashtabelle aus. Um den Aufwärmvorgang zu reduzieren, sollten wir die Anfangskapazität mit Bedacht wählen. Wenn die Anfangskapazität größer ist als die maximale Anzahl von Einträgen dividiert durch den Auslastungsfaktor, findet nie ein Rehash-Vorgang statt.

Notiz: Die Implementierung in einem HashSet ist nicht synchronisiert, d. h. wenn mehrere Threads gleichzeitig auf einen Hash-Satz zugreifen und mindestens einer der Threads den Satz ändert, muss er extern synchronisiert werden. Dies wird normalerweise durch die Synchronisierung eines Objekts erreicht, das die Menge auf natürliche Weise kapselt. Wenn kein solches Objekt vorhanden ist, sollte der Satz mithilfe der Collections.synchronizedSet-Methode umschlossen werden. Dies geschieht am besten zum Zeitpunkt der Erstellung, um einen versehentlichen, nicht synchronisierten Zugriff auf das Set zu verhindern, wie unten gezeigt:

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

Mit HashSet verwendete Methoden

1. Von der Klasse java.util.AbstractSet geerbte Methoden

Methode

Beschreibung

gleich() Wird verwendet, um die Gleichheit eines Objekts mit einem HashSet zu überprüfen und sie zu vergleichen. Die Liste gibt nur dann „true“ zurück, wenn beide HashSets unabhängig von der Reihenfolge dieselben Elemente enthalten.
Hash-Code() Gibt den Hash-Codewert für diesen Satz zurück.
RemoveAll(Sammlung) Mit dieser Methode werden alle im Set vorhandenen Elemente aus der Sammlung entfernt. Diese Methode gibt true zurück, wenn sich diese Menge durch den Aufruf ändert.

2. Von der Klasse java.util.AbstractCollection geerbte Methoden

METHODE

BESCHREIBUNG

addAll(collection)

Mit dieser Methode werden alle Elemente aus der genannten Sammlung an die vorhandene Menge angehängt.

Die Elemente werden zufällig hinzugefügt, ohne eine bestimmte Reihenfolge einzuhalten.

enthältAlle(Sammlung)

Mit dieser Methode wird überprüft, ob die Menge alle in der angegebenen Sammlung vorhandenen Elemente enthält oder nicht.

Diese Methode gibt true zurück, wenn die Menge alle Elemente enthält, und false, wenn eines der Elemente fehlt.

keepAll(collection) Diese Methode wird verwendet, um alle Elemente aus der Menge beizubehalten, die in der angegebenen Sammlung erwähnt werden. Diese Methode gibt true zurück, wenn sich dieser Satz durch den Aufruf geändert hat.
toArray() Diese Methode wird verwendet, um ein Array mit denselben Elementen wie das Set zu bilden.
toString() Die toString()-Methode von Java HashSet wird verwendet, um eine String-Darstellung der Elemente der HashSet-Sammlung zurückzugeben.

3. In der Schnittstelle java.util.Collection deklarierte Methoden

METHODE

BESCHREIBUNG

parallelStream() Gibt einen möglicherweise parallelen Stream mit dieser Sammlung als Quelle zurück.
removeIf?(Prädikatfilter) Entfernt alle Elemente dieser Sammlung, die das angegebene Prädikat erfüllen.
Strom() Gibt einen sequentiellen Stream mit dieser Sammlung als Quelle zurück.
toArray?(IntFunction-Generator) Gibt ein Array zurück, das alle Elemente in dieser Sammlung enthält, und verwendet die bereitgestellte Generatorfunktion, um das zurückgegebene Array zuzuordnen.

4. In der Schnittstelle java.lang.Iterable deklarierte Methoden

METHODE

BESCHREIBUNG

forEach?(Verbraucheraktion) Führt die angegebene Aktion für jedes Element des Iterable aus, bis alle Elemente verarbeitet wurden oder die Aktion eine Ausnahme auslöst.

5. In der Schnittstelle java.util.Set deklarierte Methoden

METHODE

BESCHREIBUNG

addAll?(Sammlung c) Fügt alle Elemente in der angegebenen Sammlung zu diesem Satz hinzu, sofern sie noch nicht vorhanden sind (optionaler Vorgang).
enthältAlle?(Sammlung c) Gibt „true“ zurück, wenn dieser Satz alle Elemente der angegebenen Sammlung enthält.
gleich?(Objekt o) Vergleicht das angegebene Objekt mit dieser Menge auf Gleichheit.
Hash-Code() Gibt den Hash-Codewert für diesen Satz zurück.
RemoveAll?(Sammlung c) Entfernt aus dieser Menge alle Elemente, die in der angegebenen Sammlung enthalten sind (optionaler Vorgang).
keepAll?(Sammlung c) Behält nur die Elemente in diesem Satz, die in der angegebenen Sammlung enthalten sind (optionaler Vorgang).
toArray() Gibt ein Array zurück, das alle Elemente in dieser Menge enthält.
toArray?(T[] a) Gibt ein Array zurück, das alle Elemente in dieser Menge enthält; Der Laufzeittyp des zurückgegebenen Arrays ist der des angegebenen Arrays.

FAQs in HashSet in Java

Q1. Was ist HashSet in Java?

Antwort:

Zufallszahl zwischen 1 und 10

HashSet ist eine Art Klasse, die AbstractSet erweitert und Set-Schnittstellen implementiert.

Q2. Warum wird HashSet verwendet?

Antwort:

HashSet wird verwendet, um doppelte Daten zu vermeiden und mit der schnellen Methode Werte zu finden.

Q3. Unterschiede zwischen HashSet und HashMap.

Antwort:

Basis

HashSet

HashMap

Implementierung HashSet implementiert eine Set-Schnittstelle. HashMap implementiert eine StoresMap-Schnittstelle.
Duplikate HashSet lässt keine doppelten Werte zu. HashMap speichert die Schlüssel-Wert-Paare und lässt keine doppelten Schlüssel zu. Wenn der Schlüssel doppelt vorhanden ist, wird der alte Schlüssel durch den neuen Wert ersetzt.
Anzahl der Objekte beim Speichern von Objekten HashSet erfordert nur ein Objekt add (Object o). HashMap erfordert zwei Objekte (K-Taste, V-Wert), um dem HashMap-Objekt ein Element hinzuzufügen.
Dummy-Wert HashSet verwendet intern HashMap, um Elemente hinzuzufügen. In HashSet dient das in der Methode add(Object) übergebene Argument als Schlüssel K. Java ordnet intern jedem in der Methode add(Object) übergebenen Wert einen Dummy-Wert zu. HashMap kennt kein Dummy-Wert-Konzept.
Speichern oder Hinzufügen eines Mechanismus HashSet verwendet intern das HashMap-Objekt, um die Objekte zu speichern oder hinzuzufügen. HashMap verwendet intern Hashing, um Objekte zu speichern oder hinzuzufügen
Schneller HashSet ist langsamer als HashMap. HashMap ist schneller als HashSet.
Einfügen HashSet verwendet die Methode add() zum Hinzufügen oder Speichern von Daten. HashMap verwendet die Methode put() zum Speichern von Daten.
Beispiel HashSet ist eine Menge, z.B. {1, 2, 3, 4, 5, 6, 7}. HashMap ist eine Schlüssel->Wert-Paar-Zuordnung (Schlüssel zu Wert), z.B. {a -> 1, b -> 2, c -> 2, d -> 1}.

Q4. Unterschiede zwischen HashSet und TreeSet in Java.

Antwort:

Basis

HashSet

TreeSet

Geschwindigkeit und interne Umsetzung der Wurfaktion Für Vorgänge wie Suchen, Einfügen und Löschen. Für diese Vorgänge wird im Durchschnitt eine konstante Zeit benötigt. HashSet ist schneller als TreeSet. HashSet wird mithilfe einer Hash-Tabelle implementiert. TreeSet benötigt O(Log n) zum Suchen, Einfügen und Löschen, was höher ist als HashSet. Aber TreeSet behält sortierte Daten. Außerdem unterstützt es Operationen wie „higher()“ (gibt das am wenigsten höhere Element zurück), „floor()“, „floor()“ usw. Diese Operationen sind in TreeSet ebenfalls „O(Log n)“ und werden in „HashSet“ nicht unterstützt. TreeSet wird mithilfe eines selbstausgleichenden binären Suchbaums (Rot-Schwarz-Baum) implementiert. TreeSet wird von TreeMap in Java unterstützt.
Bestellung Elemente in HashSet sind nicht geordnet. TreeSet verwaltet Objekte in sortierter Reihenfolge, die entweder durch die Comparable- oder Comparator-Methode in Java definiert wird. TreeSet-Elemente werden standardmäßig in aufsteigender Reihenfolge sortiert. Es bietet verschiedene Methoden zum Umgang mit der geordneten Menge wie first(), last(), headSet(), tailSet() usw.
Nullobjekt HashSet erlaubt das Nullobjekt. TreeSet lässt kein Null-Objekt zu und löst eine NullPointerException aus. Der Grund liegt darin, dass TreeSet die Methode „compareTo()“ zum Vergleichen von Schlüsseln verwendet und „compareTo()“ eine java.lang.NullPointerException auslöst.
Vergleich HashSet verwendet die Methode equal(), um zwei Objekte im Set zu vergleichen und Duplikate zu erkennen. TreeSet verwendet die Methode „compareTo()“ für denselben Zweck. Wenn „equals()“ und „compareTo()“ nicht konsistent sind, d. h. für zwei gleiche Objekte sollte „equals“ „true“ zurückgeben, während „compareTo()“ Null zurückgeben sollte, dann wird der Vertrag der Set-Schnittstelle gebrochen und Duplikate in Set-Implementierungen wie TreeSet zugelassen