1. Hashtable ist eine Unterklasse von Dictionary.
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse Hashtable<K,V>
erweitert Dictionary<K,V>
implementiert Map<K,V>, Cloneable, java.io.Serializable
HashMap:
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse HashMap<K,V>
erweitert AbstractMap<K,V>
implementiert Map<K,V>, Cloneable, Serializable
HashMap und Hashtable sind beide Implementierungsklassen der Map-Schnittstelle;
2. Die Methoden in Hashtable sind synchron (), aber die Methoden in HashMap sind standardmäßig nicht synchron. Das heißt, in Multithread-Anwendungen kann Hashtable sicher verwendet werden, ohne dass spezielle Vorgänge erforderlich sind. Für HashMap ist ein zusätzlicher Synchronisierungsmechanismus erforderlich. Das Synchronisationsproblem von HashMap kann jedoch durch eine statische Sammlungsmethode gelöst werden:
Kopieren Sie den Codecode wie folgt:
öffentliche statische <K,V> Map<K,V> synchronisiertMap(Map<K,V> m)
Diese Methode gibt eine synchronisierte Map zurück, was bedeutet, dass die zurückgegebene Map threadsicher ist. Es ist zu beachten, dass Sie beim Durchlaufen der zurückgegebenen Karte eine manuelle Synchronisierung auf der zurückgegebenen Karte durchführen müssen, da dies sonst zu undefiniertem Verhalten führt:
Kopieren Sie den Codecode wie folgt:
Map m = Collections.synchronizedMap(new HashMap());
...
Set s = m.keySet(); // Muss nicht im synchronisierten Block sein
...
synchronisiert(m) { // Synchronisierung auf m, nicht auf s!
Iterator i = s.iterator(); // Muss im synchronisierten Block sein
while (i.hasNext())
foo(i.next());
}
3. In HashMap kann null als Schlüssel verwendet werden, und es kann nur einen solchen Schlüssel geben, dessen entsprechender Wert null ist. Wenn die Methode get() einen Nullwert zurückgibt, kann dies bedeuten, dass der Schlüssel nicht in der HashMap vorhanden ist, oder es kann auch bedeuten, dass der dem Schlüssel entsprechende Wert null ist. Daher kann in HashMap die Methode get () nicht verwendet werden, um zu bestimmen, ob ein bestimmter Schlüssel in HashMap vorhanden ist. Zur Bestimmung sollte jedoch die Methode containsKey () verwendet werden. Der Schlüsselwert von Hashtable darf nicht null sein, andernfalls: java.lang.NullPointerException.
4.HashTable verwendet Enumeration und HashMap verwendet Iterator.
Bei den oben genannten Unterschieden handelt es sich nur um oberflächliche Unterschiede, und auch ihre Implementierungen sind sehr unterschiedlich.
5. Die Standardgröße des Hash-Arrays in HashTable beträgt 11 und die Erhöhungsmethode ist alt*2+1. Die Standardgröße des Hash-Arrays in HashMap beträgt 16 und muss ein Exponent von 2 sein.
6. Die Verwendung von Hash-Werten ist unterschiedlich. HashTable verwendet direkt den HashCode des Objekts.
Kopieren Sie den Codecode wie folgt:
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFFF) % tab.length;
HashMap berechnet den Hash-Wert neu und verwendet AND anstelle von Modulus, wie beispielsweise die Put-Methode von HashMap:
Kopieren Sie den Codecode wie folgt:
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Objekt k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
null zurückgeben;
}
Kopieren Sie den Codecode wie folgt:
static int hash(int h) {
// Diese Funktion stellt sicher, dass HashCodes, die sich nur um unterscheiden
// konstante Vielfache an jeder Bitposition haben eine Grenze
// Anzahl der Kollisionen (ungefähr 8 bei Standardlastfaktor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
Kopieren Sie den Codecode wie folgt:
static int indexFor(int h, int length) {
return h & (length-1);
}