A Collection- manchmal auch Container genannt - ist einfach ein Objekt, das mehrere Elemente zu einer Einheit zusammenfasst. Collections werden zum Speichern, Abrufen, Bearbeiten und Kommunizieren aggregierter Daten verwendet. Ein Sammlungsframework W ist eine einheitliche Architektur zum Darstellen und Bearbeiten von Sammlungen.
Die HashMap JDK1.2und die Hashtabelle JDK1.0werden beide verwendet, um eine Gruppe von Objekten darzustellen, die <Key, Value>paarweise dargestellt werden. Jedes <Key, Value>Paar heißt EntryObjekt. Die Sammlung von Einträgen wird durch den Gegenstand von HashMapund bezeichnet Hashtable. Schlüssel in einer Sammlung müssen eindeutig oder unverwechselbar sein. [da sie verwendet werden, um einen zugeordneten Wert eines bestimmten Schlüssels abzurufen. Werte in einer Sammlung können dupliziert werden.]
« Mitglied des Superclass, Legacy and Collection Framework
Hashtable ist eine in eingeführte Legacy-Klasse JDK1.0, die eine Unterklasse der Dictionary-Klasse ist. From JDK1.2Hashtable wurde überarbeitet, um die Map-Schnittstelle zu implementieren und Mitglied des Collection-Frameworks zu werden. HashMap ist seit Beginn seiner Einführung in Java Collection Framework Mitglied JDK1.2. HashMap ist die Unterklasse der AbstractMap-Klasse.
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
« Anfangskapazität und Lastfaktor
Die Kapazität ist die Anzahl der Buckets in der Hash-Tabelle, und die anfängliche Kapazität ist einfach die Kapazität zum Zeitpunkt der Erstellung der Hash-Tabelle. Beachten Sie, dass die Hash-Tabelle geöffnet ist: Im Fall eines " hashcollision" speichert ein einzelner Bucket mehrere Einträge, die nacheinander durchsucht werden müssen. Der Auslastungsfaktor ist ein Maß dafür, wie voll die Hash-Tabelle werden darf, bevor ihre Kapazität automatisch erhöht wird.
HashMap erstellt eine leere Hash-Tabelle mit der Standard-Anfangskapazität (16) und dem Standard-Ladefaktor (0,75). Wobei als Hashtable eine leere Hashtable mit einer Standard-Anfangskapazität (11) und einem Lastfaktor / Füll-Verhältnis (0,75) erstellt wird.

« Strukturänderung bei Hash-Kollision
HashMap, HashtableBei Hash - Kollisionen sie speichern die Map - Einträge in verknüpften Listen. Wenn in Java8 derHashMap Hash-Bucket einen bestimmten Schwellenwert überschreitet, wechselt dieser Bucket von linked list of entries to a balanced tree. die die Worst-Case-Leistung von O (n) auf O (log n) verbessern. Beim Konvertieren der Liste in einen Binärbaum wird Hashcode als Verzweigungsvariable verwendet. Wenn sich zwei verschiedene Hashcodes im selben Bucket befinden, wird einer als größer angesehen und befindet sich rechts vom Baum und der andere links. Wenn jedoch beide Hashcodes gleich sind, wird HashMapdavon ausgegangen, dass die Schlüssel vergleichbar sind, und der Schlüssel wird verglichen, um die Richtung zu bestimmen, damit eine bestimmte Reihenfolge beibehalten werden kann. Es ist eine gute Praxis, die Schlüssel HashMap vergleichbar zu machen . Beim Hinzufügen von Einträgen, wenn die Bucket-Größe erreicht istTREEIFY_THRESHOLD = 8Konvertieren Sie die verknüpfte Liste von Einträgen in einen ausgeglichenen Baum. Wenn Sie Einträge entfernen, die kleiner als TREEIFY_THRESHOLD und höchstens sind, UNTREEIFY_THRESHOLD = 6wird der ausgeglichene Baum wieder in eine verknüpfte Liste von Einträgen konvertiert . Java 8 SRC , Stackpost
« Iteration der Sammlungsansicht, ausfallsicher und ausfallsicher
+--------------------+-----------+-------------+
| | Iterator | Enumeration |
+--------------------+-----------+-------------+
| Hashtable | fail-fast | safe |
+--------------------+-----------+-------------+
| HashMap | fail-fast | fail-fast |
+--------------------+-----------+-------------+
| ConcurrentHashMap | safe | safe |
+--------------------+-----------+-------------+
Iteratorist ein Fail-Fast in der Natur. Das heißt, es wird eine ConcurrentModificationException ausgelöst, wenn eine Sammlung geändert wird, während eine andere als die eigene remove () -Methode iteriert wird. Wo wie Enumerationin der Natur ausfallsicher ist. Es werden keine Ausnahmen ausgelöst, wenn eine Sammlung während der Iteration geändert wird.
Laut Java API Docs wird Iterator immer der Aufzählung vorgezogen.
HINWEIS: Die Funktionalität der Enumeration-Schnittstelle wird von der Iterator-Schnittstelle dupliziert. Darüber hinaus fügt Iterator eine optionale Entfernungsoperation hinzu und verfügt über kürzere Methodennamen. Neue Implementierungen sollten die Verwendung von Iterator anstelle von Enumeration in Betracht ziehen.
In Java 5 wurde die ConcurrentMap-Schnittstelle eingeführt : ConcurrentHashMap- Eine hochkonkurrierende, leistungsstarke ConcurrentMapImplementierung, die von einer Hash-Tabelle unterstützt wird. Diese Implementierung wird beim Abrufen niemals blockiert und ermöglicht es dem Client, die Parallelitätsstufe für Aktualisierungen auszuwählen. Es ist als Ersatz für Folgendes gedacht Hashtable: Zusätzlich zur Implementierung ConcurrentMapunterstützt es alle "Legacy" -Methoden, die es gibt Hashtable.
Jeder HashMapEntrys-Wert ist flüchtig, wodurch eine feine Kornkonsistenz für konkurrierende Modifikationen und nachfolgende Lesevorgänge sichergestellt wird. Jeder Lesevorgang spiegelt das zuletzt abgeschlossene Update wider
Iteratoren und Aufzählungen sind ausfallsicher - spiegeln den Status zu einem bestimmten Zeitpunkt seit der Erstellung des Iterators / der Aufzählung wider. Dies ermöglicht gleichzeitiges Lesen und Ändern auf Kosten einer verringerten Konsistenz. Sie lösen keine ConcurrentModificationException aus. Iteratoren können jedoch jeweils nur von einem Thread verwendet werden.
Wie, Hashtableaber HashMapnicht, erlaubt diese Klasse nicht, dass Null als Schlüssel oder Wert verwendet wird.
public static void main(String[] args) {
//HashMap<String, Integer> hash = new HashMap<String, Integer>();
Hashtable<String, Integer> hash = new Hashtable<String, Integer>();
//ConcurrentHashMap<String, Integer> hash = new ConcurrentHashMap<>();
new Thread() {
@Override public void run() {
try {
for (int i = 10; i < 20; i++) {
sleepThread(1);
System.out.println("T1 :- Key"+i);
hash.put("Key"+i, i);
}
System.out.println( System.identityHashCode( hash ) );
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
new Thread() {
@Override public void run() {
try {
sleepThread(5);
// ConcurrentHashMap traverse using Iterator, Enumeration is Fail-Safe.
// Hashtable traverse using Enumeration is Fail-Safe, Iterator is Fail-Fast.
for (Enumeration<String> e = hash.keys(); e.hasMoreElements(); ) {
sleepThread(1);
System.out.println("T2 : "+ e.nextElement());
}
// HashMap traverse using Iterator, Enumeration is Fail-Fast.
/*
for (Iterator< Entry<String, Integer> > it = hash.entrySet().iterator(); it.hasNext(); ) {
sleepThread(1);
System.out.println("T2 : "+ it.next());
// ConcurrentModificationException at java.util.Hashtable$Enumerator.next
}
*/
/*
Set< Entry<String, Integer> > entrySet = hash.entrySet();
Iterator< Entry<String, Integer> > it = entrySet.iterator();
Enumeration<Entry<String, Integer>> entryEnumeration = Collections.enumeration( entrySet );
while( entryEnumeration.hasMoreElements() ) {
sleepThread(1);
Entry<String, Integer> nextElement = entryEnumeration.nextElement();
System.out.println("T2 : "+ nextElement.getKey() +" : "+ nextElement.getValue() );
//java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode
// at java.util.HashMap$EntryIterator.next
// at java.util.Collections$3.nextElement
}
*/
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
Map<String, String> unmodifiableMap = Collections.unmodifiableMap( map );
try {
unmodifiableMap.put("key4", "unmodifiableMap");
} catch (java.lang.UnsupportedOperationException e) {
System.err.println("UnsupportedOperationException : "+ e.getMessage() );
}
}
static void sleepThread( int sec ) {
try {
Thread.sleep( 1000 * sec );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
« Nullschlüssel und Nullwerte
HashMaperlaubt maximal einen Nullschlüssel und eine beliebige Anzahl von Nullwerten. Wenn as Hashtablenicht einmal einen einzelnen Nullschlüssel und einen Nullwert zulässt, wird, wenn der Schlüssel oder Wert Null ist, eine NullPointerException ausgelöst. Beispiel
« Synchronisiert, threadsicher
Hashtableist intern synchronisiert. Daher ist die Verwendung Hashtablein Multithread-Anwendungen sehr sicher . Wobei as HashMapnicht intern synchronisiert ist. Daher ist die Verwendung HashMapin Multithread-Anwendungen ohne externe Synchronisierung nicht sicher . Sie können HashMapmithilfe der Collections.synchronizedMap()Methode extern synchronisieren .
« Leistung
Da Hashtableintern synchronisiert, macht dies Hashtableetwas langsamer als die HashMap.
@Sehen