1.继承父类不同
HashMap继承自AbstractMap<K,V>类,而HashTable继承自Dictionary<K,V>类。
不过它们都实现了同时实现了map、Cloneable(可复制)、Serializable(可序列化)这三个接口
Dictionary类是一个已经被废弃的类(见其源码中的注释)。父类都被废弃,自然而然也没人用它的子类Hashtable了。
- NOTE: This class is obsolete. New implementations should
- implement the Map interface, rather than extending this class.!
2.对外提供接口不同
Hashtable比HashMap多提供了elments() 和contains() 两个方法。
elments() 方法继承自Hashtable的父类Dictionnary。elements() 方法用于返回此Hashtable中的value的枚举。
contains() 方法判断该Hashtable是否包含传入的value。
它的作用与containsValue()一致。事实上,contansValue() 就只是调用了一下contains() 方法。
3.对Null key 和Null value的支持不同
HashTable()既不支持Null Key也不支持Null Value,在HashTable()的put方法注释中有说明.
当key为Null时,调用put() 方法,运行到下面这一步就会抛出空指针异常。因为拿一个Null值去调用方法了。
当value值为空时,HashTable也做了限制,在这一步会抛出异常:
4.线程安全性不同
HashTable是线程安全的,在每个方法都加入了synchronized方法,在多线程并发环境下,可以直接使用HashTable,不需要自己实现同步的方法。
HashMap是线程不安全的,在多线程并发环境下,可能产生死锁等问题。使用HashMap必须自己实现同步方法。
虽然HashMap不是线程安全的,但是它的效率会比Hashtable要好很多。这样设计是合理的。在我们的日常使用当中,大部分时间是单线程操作的。HashMap把这部分操作解放出来了。当需要多线程操作的时候可以使用线程安全的ConcurrentHashMap。ConcurrentHashMap虽然也是线程安全的,但是它的效率比Hashtable要高好多倍。因为ConcurrentHashMap使用了分段锁,并不对整个数据进行锁定。
5.初始容量大小和每次扩充容量大小的不同
Hashtable默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。
HashTable:
HashMap:
创建时,如果给定了容量初始值,那么Hashtable会直接使用你给定的大小,而HashMap会将其扩充为2的幂次方大小。也就是说Hashtable会尽量使用素数、奇数。而HashMap则总是使用2的幂作为哈希表的大小。