Ausführliche Erläuterung der Java-Sammlung (1) - Java-Full-Stack-Wissen (6)

1. Welche Sammlungen gibt es in Java

Die Schnittstelle der obersten Ebene unter dem java.util-Paket ist die Collection-Schnittstelle, und es gibt drei Schnittstellen unter der Collection:

  • Set: Stellt eine ungeordnete, nicht wiederholbare Sammlung dar
  • Liste: Stellt eine geordnete und wiederholbare Sammlung dar
  • Warteschlange: Zeigt eine First-In-First-Out-Warteschlange an

Zu den gängigen Implementierungsklassen gehören HashSet und TreeSet unter der Set-Schnittstelle

Die List-Schnittstelle enthält ArrayList, LinkedList, Stack usw.

Queue hat PriorityQueue für Priority Queue, ArrayDeque oder Queue LinedList implementiert durch Linked List

Map stellt eine Sammlung von (Schlüsselwert-)Typen dar, und es gibt HashMap und TreeMap unter der Schnittstelle.

2. Was sind Thread-sichere Sammlungen?

Die meisten Sammlungen unter dem java.util-Paket sind Thread-unsichere Sammlungen, und es gibt auch einige Thread-sichere Sammlungen wie: Hashtable und Vector, aber diese beiden Sammlungen sind einige alte APIs, wie aus den Namen ersichtlich ist. sogar Hashtable entspricht nicht der Java-Namenskonvention. Obwohl Thread-sicher, ist die Effizienz im Vergleich zu anderen häufig verwendeten Sammlungen sehr schlecht. Wenn wir also eine Thread-sichere Sammlung verwenden müssen, können wir Collections verwenden, um HashMap in eine Thread-sichere Map zu verpacken. Die spezifische Operation ist wie folgt:

Map<String,String> unSafeMap = new HashMap<String,String>();
Karte safeMap = Collections.synchronizedMap(unSafeMap);

Oder Sie verwenden die entsprechende Sammlung unter dem Paket java.util.concurrent.

Nach jdk1.5 führte Java das Paket java.util.concurrent ein, um Thread-sichere Implementierungsklassen für häufig verwendete Sammlungen zu implementieren: "

  • Sammlungsklassen, die mit Concurrent beginnen: Sammlungsklassen, die mit Concurrent beginnen, stellen Sammlungen dar, die den gleichzeitigen Zugriff unterstützen. Sie können den gleichzeitigen Schreibzugriff durch mehrere Threads unterstützen. Alle Operationen dieser schreibenden Threads sind Thread-sicher, aber Leseoperationen müssen nicht gesperrt werden. Sammlungsklassen, die mit Concurrent beginnen, verwenden einen komplexeren Algorithmus, um sicherzustellen, dass die gesamte Sammlung niemals gesperrt wird, sodass sie beim gleichzeitigen Schreiben eine bessere Leistung aufweisen.
  • Sammlungsklassen, die mit CopyOnWrite beginnen: Sammlungsklassen, die mit CopyOnWrite beginnen, implementieren Schreibvorgänge, indem sie das zugrunde liegende Array kopieren. Wenn ein Thread eine Leseoperation für eine solche Sammlung durchführt, liest der Thread die Sammlung selbst direkt, ohne sie zu sperren oder zu blockieren. Wenn ein Thread einen Schreibvorgang für eine solche Sammlung ausführt, kopiert die Sammlung ein neues Array ganz unten und führt dann einen Schreibvorgang für das neue Array aus. Da Schreibvorgänge in eine Sammlung auf einer Kopie des Arrays ausgeführt werden, ist sie Thread-sicher.

3. Die Implementierungsklasse der Map-Schnittstelle

Unter der Kartenschnittstelle gibt es vier allgemeine Implementierungsklassen: HashMap, TreeMap, ConcurrentHashMap und LinkedHashMap.

Wählen Sie die zu verwendende Kartensammlung entsprechend der Nutzung aus:

  • Wenn Sie nur eine Kartensammlung benötigen, ohne Sortier- und Thread-Sicherheitsprobleme zu berücksichtigen, ist HashMap die beste Wahl, da HashMap die höchste Effizienz aufweist und die Zeitkomplexität von Abfrage, Einfügung und Löschung O (1) beträgt.
  • Wenn Sie die Threadsicherheit berücksichtigen und Sortierprobleme nicht in Betracht ziehen, können Sie ConcurrentHashMap verwenden, das durch den Mechanismus von CAS oder Segmentsperre threadsicher ist
  • Wenn eine Sortierung erforderlich ist und nur eine natürliche Einfügungssortierung erforderlich ist, kann LinkedHashMap verwendet werden.
  • Wenn Sie die Sortierregeln anpassen müssen, verwenden Sie TreeMap. Die unterste Ebene von TreeMap wird durch Rot-Schwarz-Bäume implementiert und unterstützt das Sortieren.
  • Wenn Sie Sortierung und Threadsicherheit benötigen, können Sie die Toolklasse Collections verwenden, um eine threadsichere Sammlung zu erstellen.

4. Der Unterschied zwischen TreeMap und HashMap

  1. HashMap ist implementiert basierend auf Hash-Tabelle und verknüpfter Liste (vor jdk1.8), basierend auf Hash-Tabelle + verknüpfter Liste + Rot-Schwarz-Baum (ab 1.8)
  2. HashMap ist effizienter, da es basierend auf einer Hash-Tabelle implementiert wird, sodass die Zeitkomplexität O (1) beträgt, TreeMap basierend auf einem Rot-Schwarz-Baum implementiert wird und die Abfrageeffizienz O (log2 N) beträgt.
  3. TreeMap ist eine geordnete Sammlung und HashMap ist ungeordnet, bestimmt durch die zugrunde liegende Datenstruktur.
  4. Beides ist nicht threadsicher

5. Der Mechanismus von HashMap

Nach jdk1.8 änderte sich die zugrunde liegende Datenstruktur von hashMap von Hash-Tabelle + verkettete Liste zu Hash-Tabelle + verkettete Liste + rot-schwarzer Baum. Denn bei schwerwiegenden Hash-Konflikten wird verhindert, dass die verkettete Liste hinter jeder Position der Hash-Tabelle zu lang wird und die Abfrageeffizienz wird O(n).O(log2 N).

  1. Die anfängliche Kapazität von HashMap ist 16, und die Kapazität wird beim Einfügen überprüft. Wenn die Anzahl der aktuell gespeicherten Knoten größer ist als der Lastfaktor (Standard 0,75) * maximale Kapazität (Standard 16), wird HashMap mit der doppelten Kapazität erweitert.
  2. Um Hash-Konflikte zu lösen, werden die Elemente in der Hash-Tabelle in einer einseitig verknüpften Liste gespeichert. Nachdem die Länge der verknüpften Liste einen Schwellenwert (standardmäßig 8) erreicht hat, wird die zugrunde liegende verknüpfte Liste als rot konstruiert. schwarzer Baum, um die Leistung zu verbessern. Wenn wir Elemente löschen, bis die Länge der verknüpften Liste 6 beträgt. Der Rot-Schwarz-Baum wird automatisch in eine verknüpfte Liste umgewandelt, um die Leistung zu verbessern.
  3. Bevor die Länge der verketteten Liste überprüft und in einen Rot-Schwarz-Baum umgewandelt wird, prüft es auch, ob das aktuelle Array array einen Schwellenwert erreicht (64) Wenn es diese Kapazität nicht erreicht, wird die Umwandlung abgebrochen und das Array wird zunächst ausgebaut.

5.1 Warum müssen Sie die Größe für die Erweiterung verdoppeln?

Die Gruppenlänge wird doppelt so groß wie die ursprüngliche, was bedeutet, dass in der Binärdatei ein extra hohes Bit an der Bestimmung des Array-Index beteiligt ist . Nachdem ein Element mit der Methode der Hash-Konvertierungskoordinaten berechnet wurde, tritt zu diesem Zeitpunkt ein Phänomen auf: Das höchste Bit ist 0, die Koordinaten bleiben unverändert, und das höchste Bit ist 1, die Koordinaten werden zu "10000 + ursprüngliche Koordinaten “, also „ursprüngliche Länge + ursprüngliche Koordinaten“.

5.2 Warum sind die Schwellenwerte 8 und 6 statt größer oder gleich 8 und kleiner als 8?

Da einige HashMaps während der Verwendung häufig Elemente hinzufügen und löschen können, wodurch die Länge der verknüpften Liste häufig zwischen 7 und 8 schwankt. Wenn der Schwellenwert zu diesem Zeitpunkt 8 beträgt, werden häufig Rot-Schwarz-Bäume und verknüpfte Listen erstellt. Dann werden viele Systemressourcen verschwendet, um die zugrunde liegende Datenstruktur zu konvertieren. Der Zweck des Eintritts in den rot-schwarzen Baum ist die Effizienzsteigerung. Zu diesem Zeitpunkt kann der Effekt der Effizienzsteigerung nicht erreicht werden, aber die Effizienz wird reduziert.

5.3 Warum verwendet HashMap einen Rot-Schwarz-Baum anstelle von B-Baum?

Denn B/B+-Bäume eignen sich besser zum Speichern großer Datenmengen. Es ist besser für die Verwendung auf externem Speicher geeignet, und wir führen Rot-Schwarz-Bäume ein, um das Problem der reduzierten Abfrageeffizienz zu lösen, das durch zu lange verknüpfte Listen verursacht wird.Es ist unmöglich, eine große Anzahl von Elementen in einem Array-Bereich von HashMap zu speichern. Wenn die Anzahl der Elemente relativ gering ist, führt die Verwendung des B/B+-Baums dazu, dass die Daten in einen Knoten gequetscht werden, und die Effizienz ist die gleiche wie bei der verknüpften Liste.

Supongo que te gusta

Origin blog.csdn.net/dghehe/article/details/130031795
Recomendado
Clasificación