HashTable认识

  • HashTable 常用的映射功能和HashMap类似;

  • 继承Dictionary类;

  • 线程安全的集合类,任一时间只能有一个线程写hashtable;并发性不如ConcurrentHashMap,因为ConcurrentHashMap引入了Segment分段锁;

  • 在不需要线程安全中建议使用HashMap;需要线程安全的地方使用ConcurrentHashMap;

HashTable与HashMap区别

参考资料:http://www.importnew.com/24822.html

  • 区别1:对外提供调用的方法不同



从图中可以看出,两个类的继承体系有些不同。虽然都实现了Map、Cloneable、Serializable三个接口。但是HashMap继承自抽象类AbstractMap,而HashTable继承自抽象类Dictionary。其中Dictionary类是一个已经被废弃的类,这一点我们可以从它代码的注释中看到:

  • 区别2:Null Key & Null Value

HashMap是支持null键和null值的,而HashTable在遇到null时,会抛出NullPointerException异常。这并不是因为HashTable有什么特殊的实现层面的原因导致不能支持null键和null值,这仅仅是因为HashMap在实现时对null做了特殊处理,将null的hashCode值定为了0,从而将其存放在哈希表的第0个bucket中。我们一put方法为例,看一看代码的细节:

以下代码及注释来自java.util.HashTable
 
public synchronized V put(K key, V value) {
 
    // 如果value为null,抛出NullPointerException
    if (value == null) {
        throw new NullPointerException();
    }
 
    // 如果key为null,在调用key.hashCode()时抛出NullPointerException
 
    // ...
}
 
 
以下代码及注释来自java.util.HasMap
 
public V put(K key, V value) {
    if (table == EMPTY_TABLE) {
        inflateTable(threshold);
    }
    // 当key为null时,调用putForNullKey特殊处理
    if (key == null)
        return putForNullKey(value);
    // ...
}
 
private V putForNullKey(V value) {
    // key为null时,放到table[0]也就是第0个bucket中
    for (Entry<K,V> e = table[0]; e != null; e = e.next) {
        if (e.key == null) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }
    modCount++;
    addEntry(0, null, value, 0);
    return null;
}
  • 区别3: 线程安全

我们说HashTable是同步的,HashMap不是,也就是说HashTable在多线程使用的情况下,不需要做额外的同步,而HashMap则不行。那么HashTable是怎么做到的呢?
以下代码及注释来自java.util.HashTable

public synchronized V get(Object key) {
   Entry tab[] = table;
   int hash = hash(key);
   int index = (hash & 0x7FFFFFFF) % tab.length;
   for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
       if ((e.hash == hash) && e.key.equals(key)) {
           return e.value;
       }
   }
   return null;
}

public Set<K> keySet() {
   if (keySet == null)
       keySet = Collections.synchronizedSet(new KeySet(), this);
   return keySet;
}

HashTable已经被淘汰了,不要在代码中再使用它。