An analysis of the differences between Hashtable and HashMap in Java

  • 2020-04-01 01:39:41
  • OfStack

1. Hashtable is a subclass of Dictionary,


 public class Hashtable<K,V>
     extends Dictionary<K,V>
     implements Map<K,V>, Cloneable, java.io.Serializable 

A HashMap:

public class HashMap<K,V>
    extends AbstractMap<K,V>
     implements Map<K,V>, Cloneable, Serializable 

Both HashMap and Hashtable are an implementation class of the Map interface.

2. Methods in Hashtable are synchronized (), while methods in HashMap are not synchronized by default. That is, in a multithreaded application, Hashtable is safe to use without special operations; For HashMap, an additional synchronization mechanism is required. But the synchronization problem for HashMap can be solved with a static method in Collections:


public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)

This method returns a synchronized Map, which means that the returned Map is thread-safe. It is important to note that when iterating over the returned map, synchronization on the returned map must be performed manually, otherwise it will lead to uncertain behavior:

Map m = Collections.synchronizedMap(new HashMap());
       ...
   Set s = m.keySet();  // Needn't be in synchronized block
       ...
   synchronized(m) {  // Synchronizing on m, not s!
       Iterator i = s.iterator(); // Must be in synchronized block
       while (i.hasNext())
           foo(i.next());
   }

3. In a HashMap, null can be used as a key; there is only one such key; There can be one or more keys that correspond to a value of null. When the get() method returns a null value, you can either indicate that the key is not in the HashMap or that the value corresponding to the key is null. Therefore, instead of the get() method in a HashMap determining whether a key exists in a HashMap, use the containsKey() method. Hashtable key value cannot be null, otherwise: Java. Lang. NullPointerException.
4.HashTable USES Enumeration, and HashMap USES Iterator.
These are only superficial differences, and their implementations are quite different.
5. The default size of the hash array in HashTable is 11, and the increment is old*2+1. The default size of the hash array in a HashMap is 16, and it must be an exponent of 2.
6. Different hash values are used. HashTable directly USES the hashCode of the object.


int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;

While HashMap recalculates the hash value, and USES and instead to evaluate the modulus, such as HashMap's put method:


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) {
             Object 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);
         return null;
     }


static int hash(int h) {
         // This function ensures that hashCodes that differ only by
         // constant multiples at each bit position have a bounded
         // number of collisions (approximately 8 at default load factor).
         h ^= (h >>> 20) ^ (h >>> 12);
         return h ^ (h >>> 7) ^ (h >>> 4);
     }


   static int indexFor(int h, int length) {
         return h & (length-1);
     }


Related articles: