Karten. Sie bergen vielleicht keine verborgenen Schätze oder markieren den „X“-Punkt bei Ihrer Suche nach Gold, aber sie sind eine Fundgrube in der Java-Entwicklung. Ganz gleich, ob Sie ein frischgebackener Entwickler oder ein erfahrener Architekt mit einer kaffeefleckigen Tastatur sind: Das Verständnis von Maps wird Ihre Programmierfähigkeiten verbessern. Begeben wir uns auf eine epische Reise durch jeden Winkel von Maps in Java.
Einfach ausgedrückt ist eine Map eine Datenstruktur, die Schlüssel-Wert-Paare speichert. Stellen Sie es sich wie ein Wörterbuch aus der realen Welt vor: Sie haben ein Wort (Schlüssel) und seine Bedeutung (Wert). Jeder Schlüssel in einer Karte muss eindeutig sein, aber Werte können dupliziert werden.
Caching: Ergebnisse speichern, um wiederholte Berechnungen zu vermeiden.
Datenbankindizierung: Schneller Zugriff auf Daten mit Primärschlüsseln.
Konfigurationen: Speichern Sie Einstellungen und Präferenzen als Schlüssel-Wert-Paare.
Häufigkeiten zählen: Zählt das Vorkommen von Elementen (z. B. Worthäufigkeiten).
Karten glänzen in Szenarien, in denen schnelle Suchvorgänge, Einfügungen und Aktualisierungen erforderlich sind. Sie werden zum Modellieren von Beziehungen verwendet, bei denen ein eindeutiger Bezeichner (Schlüssel) einer bestimmten Entität (Wert) zugeordnet ist.
Java bietet eine Vielzahl von Karten für unterschiedliche Anforderungen:
3.1 HashMap
Implementierung: Verwendet eine Hash-Tabelle .
Leistung: O(1) durchschnittliche Zeit für Get- und Put-Vorgänge.
Eigenschaften: Ungeordnet und erlaubt einen Nullschlüssel und mehrere Nullwerte.
Speicherlayout: Schlüssel werden in einer Reihe von Buckets gespeichert; Jeder Bucket ist eine verknüpfte Liste oder ein Baum (wenn Kollisionen einen Schwellenwert überschreiten).
3.2 LinkedHashMap
Implementierung: Erweitert HashMap um eine verknüpfte Liste, um die Einfügungsreihenfolge beizubehalten.
Anwendungsfall: Wenn die Reihenfolge der Einträge beibehalten werden muss (z. B. LRU-Cache).
Leistung: Etwas niedriger als HashMap aufgrund des Overheads der verknüpften Liste.
3.3 TreeMap
Implementierung: Verwendet einen Rot-Schwarz-Baum (eine Art ausgeglichener binärer Suchbaum).
Leistung: O(log n) für Get-, Put- und Remove-Operationen.
Eigenschaften: Sortiert nach der natürlichen Reihenfolge der Schlüssel oder einem benutzerdefinierten Komparator.
3.4 Hashtabelle
Ancient History Alert: Ein Relikt aus den Anfängen von Java, synchronisiert und threadsicher, aber mit erheblichen Leistungseinbußen.
Eigenschaften: Erlaubt keine Nullschlüssel oder -werte.
3.5 ConcurrentHashMap
Thread-sicherer Held: Entwickelt für den gleichzeitigen Zugriff, ohne die gesamte Karte zu sperren.
Implementierung: Verwendet einen segmentbasierten Sperrmechanismus.
Leistung: Bietet hohen Durchsatz bei gleichzeitigem Lese-/Schreibzugriff.
4.1 HashMap im Detail
Hashing: Ein Schlüssel wird an eine Hash-Funktion übergeben, die einen Index innerhalb des Arrays (Bucket) zurückgibt.
Kollisionsauflösung: Wenn mehrere Schlüssel denselben Hash-Index erzeugen:
int hash = key.hashCode() ^ (key.hashCode() >>> 16); int index = hash & (n - 1); // n is the size of the array (usually a power of 2)
4.2 TreeMap-Interna
Rot-Schwarzer Baum: Der selbstausgleichende Baum stellt sicher, dass der längste Weg von der Wurzel zu einem Blatt nicht mehr als doppelt so lang ist wie der kürzeste Weg.
Reihenfolge: Sortiert Schlüssel automatisch entweder in natürlicher Reihenfolge oder basierend auf einem Komparator.
4.3 ConcurrentHashMap-Mechanik
Bucket-Sperre: Verwendet feinkörnige Sperren für separate Segmente, um die Parallelität zu verbessern.
Speichereffizienz: Nutzt eine Kombination aus Arrays und verknüpften Knoten.
Lassen Sie uns die am häufigsten verwendeten Methoden mit einfachen Codeausschnitten durchgehen:
5.1 put(K-Taste, V-Wert)
Fügt ein Schlüssel-Wert-Paar ein oder aktualisiert es.
Map<String, Integer> map = new HashMap<>(); map.put("Alice", 30); map.put("Bob", 25);
5.2 get(Object key)
Ruft den mit einem Schlüssel verknüpften Wert ab.
int age = map.get("Alice"); // 30
5.3 enthältSchlüssel(Objektschlüssel)
Überprüft, ob die Karte einen bestimmten Schlüssel enthält.
boolean exists = map.containsKey("Bob"); // true
5.4 entfernen (Objektschlüssel)
Entfernt die Zuordnung für einen bestimmten Schlüssel.
map.remove("Bob");
5.5 EntrySet(), KeySet(), Values()
Iteriert über Einträge, Schlüssel oder Werte.
for (Map.Entry<String, Integer> entry : map.entrySet()) { System.out.println(entry.getKey() + " = " + entry.getValue()); }
HashMap ist um Buckets (Arrays) herum strukturiert. Jeder Bucket zeigt auf Folgendes:
Ein einzelner Eintrag
Eine verknüpfte Liste/Baumstruktur (Kollision vorhanden).
Wenn Schlüssel1 und Schlüssel2 denselben Hash haben, wandern sie in denselben Bucket:
Vor Java 8: Verknüpfte Liste.
Java 8 : Konvertiert in einen Baum, wenn die Anzahl der Elemente in einem Bucket einen Schwellenwert überschreitet.
Visuelle Darstellung :
int hash = key.hashCode() ^ (key.hashCode() >>> 16); int index = hash & (n - 1); // n is the size of the array (usually a power of 2)
Häufige Verwendung in Algorithmen wie Worthäufigkeitszählern oder Zeichenzählung in Zeichenfolgen.
Map<String, Integer> map = new HashMap<>(); map.put("Alice", 30); map.put("Bob", 25);
int age = map.get("Alice"); // 30
Wann man Karten verwendet:
Suchlastige Aufgaben: Wenn Sie O(1)-Zeitkomplexität benötigen.
Zähl- und Häufigkeitsprobleme: Häufig bei Wettbewerbsprogrammen.
Caching und Memoisierung: Karten können zum Zwischenspeichern von Ergebnissen für dynamische Programmierung verwendet werden.
Gibt bei einem gegebenen Array von Ganzzahlen Indizes der beiden Zahlen zurück, die zusammen ein bestimmtes Ziel ergeben.
boolean exists = map.containsKey("Bob"); // true
Wenn Sie Integer als Schlüssel verwenden, denken Sie daran, dass Java ganze Zahlen von -128 bis 127 zwischenspeichert. Außerhalb dieses Bereichs werden Schlüssel möglicherweise unterschiedlich verpackt, was zu Ineffizienzen führt.
Zur Leistungsoptimierung überschreiben Sie hashCode() sorgfältig:
map.remove("Bob");
Die Verwendung veränderlicher Objekte als Schlüssel ist eine schlechte Praxis. Wenn sich das Schlüsselobjekt ändert, ist es möglicherweise nicht abrufbar.
Schlüsselwertbeziehungen: Wenn das Problem Beziehungen aufweist, bei denen ein Element einem anderen zugeordnet ist.
Doppelte Zählung: Wiederholte Elemente erkennen.
Schneller Datenabruf: Wenn eine O(1)-Suche erforderlich ist.
Karten sind eine der vielseitigsten und leistungsfähigsten Datenstrukturen in Java. Ob HashMap für allgemeine Zwecke, TreeMap für sortierte Daten oder ConcurrentHashMap für Parallelität: Wenn Sie wissen, welche Sie verwenden und wie sie funktionieren, können Sie besseren und effizienteren Code schreiben.
Wenn Sie also das nächste Mal jemand nach Maps fragt, können Sie lächeln, an Ihrem Kaffee nippen und ihm sagen: „Wo soll ich anfangen?“
Das obige ist der detaillierte Inhalt vonEin tiefer Einblick in Java Maps: Der ultimative Leitfaden für alle Entwickler. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!