Hashtable-Klasse
Hashtable erbt die Map-Schnittstelle und implementiert eine Hash-Tabelle für die Schlüsselwertzuordnung. Als Schlüssel oder Wert kann jedes Nicht-Null-Objekt verwendet werden.
Um Daten hinzuzufügen, verwenden Sie put(key,value) und um Daten zu entfernen, verwenden Sie get(key). Der Zeitaufwand dieser beiden Grundoperationen ist konstant.
Hashtable passt die Leistung über zwei Parameter an: Anfangskapazität und Auslastungsfaktor. Normalerweise erreicht der Standardlastfaktor 0,75 ein besseres Gleichgewicht zwischen Zeit und Raum. Durch Erhöhen des Auslastungsfaktors kann Platz gespart werden, die entsprechende Suchzeit erhöht sich jedoch, was sich auf Vorgänge wie „Abrufen“ und „Put“ auswirkt.
Ein einfaches Beispiel für die Verwendung von Hashtable ist wie folgt: Geben Sie 1, 2 und 3 in die Hashtable ein, und ihre Schlüssel sind „eins“, „zwei“ und „drei“:
Hashtable-Nummern = new Hashtable();
zahlen.put(“one”, new Integer(1));
zahlen.put(“two”, new Integer(2));
zahlen.put(“drei”, new Integer(3));
Um eine Zahl wie 2 abzurufen, verwenden Sie die entsprechende Taste:
Ganzzahl n = (Integer)numbers.get(“two”);
System.out.println(“two = ” + n);
Da das als Schlüssel verwendete Objekt die Position des entsprechenden Werts durch Berechnung seiner Hash-Funktion bestimmt, muss jedes als Schlüssel verwendete Objekt die Methoden hashCode und equal implementieren. Die Methoden hashCode und equal erben von der Stammklasse Object. Wenn Sie eine benutzerdefinierte Klasse als Schlüssel verwenden, müssen Sie gemäß der Definition der Hash-Funktion sehr vorsichtig sein, wenn die beiden Objekte gleich sind, d. h. obj1.equals( obj2)=true, dann muss ihr HashCode sein Das Gleiche, aber wenn zwei Objekte unterschiedlich sind, ist ihr HashCode nicht unbedingt unterschiedlich. Wenn der HashCode zweier verschiedener Objekte gleich ist, wird dieses Phänomen als Konflikt bezeichnet. Der Zeitaufwand für den Betrieb der Hash-Tabelle erhöht sich Um es gut zu definieren, kann die Methode hashCode() Hash-Tabellenoperationen beschleunigen.
Wenn dasselbe Objekt einen anderen Hash-Code hat, führt die Operation der Hash-Tabelle zu unerwarteten Ergebnissen (die erwartete Get-Methode gibt null zurück. Um dieses Problem zu vermeiden, müssen Sie sich nur eines merken: Überschreiben Sie gleichzeitig die Equals-Methode und die HashCode-Methode). Zeit. Schreiben Sie nicht nur eine davon. Hashtable ist synchron.
HashMap-Klasse
HashMap ähnelt Hashtable, mit der Ausnahme, dass HashMap asynchron ist und Nullen zulässt, d. h. Nullwerte und Nullschlüssel. , aber wenn HashMap als Sammlung behandelt wird (die Methode „values()“ kann eine Sammlung zurückgeben), ist der Zeitaufwand ihrer Iterationsunteroperationen proportional zur Kapazität der HashMap. Wenn die Leistung iterativer Operationen sehr wichtig ist, sollten Sie daher die Anfangskapazität von HashMap nicht zu hoch oder den Auslastungsfaktor zu niedrig einstellen.
WeakHashMap-Klasse
WeakHashMap ist eine verbesserte HashMap, die „schwache Referenzen“ auf Schlüssel implementiert. Wenn ein Schlüssel nicht mehr extern referenziert wird, kann der Schlüssel von GC recycelt werden.
HashSet finden Sie in der Beschreibung von Set
Set ist eine Sammlung, die keine doppelten Elemente enthält, d. h. zwei beliebige Elemente e1 und e2 haben e1.equals(e2)=false und Set hat höchstens ein Nullelement.
Der Konstruktor von Set hat die Einschränkung, dass der übergebene Collection-Parameter keine doppelten Elemente enthalten darf.
Bitte beachten Sie: Mit veränderlichen Objekten muss vorsichtig umgegangen werden. Wenn ein veränderliches Element in einem Set seinen Zustand ändert und Object.equals(Object)=true verursacht, führt dies zu einigen Problemen.
Zwei gängige Set-Implementierungen sind HashSet und TreeSet. Die Entscheidung, welches Sie verwenden möchten, ist ziemlich einfach. HashSet ist viel schneller (konstante Zeit vs. Protokollzeit für die meisten Vorgänge), bietet jedoch keine Bestellgarantien. Wenn Sie die Operationen in einem SortedSet verwenden müssen oder Ihnen eine sequentielle Iteration wichtig ist, verwenden Sie ein TreeSet. Andernfalls verwenden Sie ein HashSet. Es ist ein faires Risiko für Sie, die meiste Zeit kein HashSet zu verwenden.
Bei HashSets sollten Sie bedenken, dass die Iteration im Hinblick auf die Summe der Anzahl der Einträge und der Kapazität linear ist. Wenn daher die Iterationsleistung wichtig ist, sollte eine geeignete Anfangskapazität sorgfältig ausgewählt werden. Die Wahl einer zu großen Kapazität verschwendet sowohl Platz als auch Zeit. Die standardmäßige Anfangskapazität beträgt 101, was im Allgemeinen mehr ist, als Sie benötigen. Sie können den int-Konstruktor verwenden, um die Anfangskapazität anzugeben. Die anfängliche Kapazität des zuzuweisenden HashSet beträgt 17:
Setze s= new HashSet(17);
HashSets verfügen außerdem über einen „Tuning-Parameter“, den sogenannten Lastfaktor. Wenn Sie sich große Sorgen über die Speicherplatznutzung Ihres HashSets machen, lesen Sie den HashSet-Text für weitere Details. Andernfalls verwenden Sie einfach den Standardwert. Wenn Sie den Standardladefaktor akzeptieren, aber dennoch eine Anfangskapazität angeben möchten, wählen Sie eine Zahl, die ungefähr dem Doppelten der Kapazität entspricht, auf die Ihr Set voraussichtlich anwachsen wird. Wenn Ihre Schätzung falsch ist, kann es wachsen oder einfach ein wenig Platz verschwenden. Aber es gibt keine großen Probleme. Wenn Sie den besten Wert für die richtige Größe kennen, verwenden Sie ihn. Wenn Sie ihn nicht kennen, verwenden Sie einen alten Wert oder einen geraden Wert. Es ist wirklich nicht sehr wichtig. Diese Dinge machen HashSet nur geringfügig besser.
TreeSet hat keine Optimierungsparameter. Zusätzlich zum Klonen verfügen HashSet und TreeSet nur über die Operationen, die für ihre jeweiligen Schnittstellen (Set und TreeSet) erforderlich sind, und über keine anderen Operationen.