1、继承不同
Hashtable
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable {
HashMap
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
- HashMap和Hashtable 都实现了Map、Cloneable、Serializable接口 所以实现是相同的
- HashMap 继承自 AbstractMap Hashtable继承自Dictionary 继承不同.注意 Dictionary是一个过时的类
2、key value 对null的支持
HashMap可用有一个key为null,值可用为null.但Hashtable不能有key和value都不能为空。
HashMap的key可用为null那么我们就不可以通过根据get()返回的结果去判断是否为空进而判断是否包含此key.如何要判断是否包含那么要HashMap的 containsKey()
3、线程安全
HashMap不是线程安全,在多线程环境下需要自己做同步处理。Hashtable是线程安全的,在多线程环境中可用直接所以。但是性能比较低。而且Hashtable已经淘汰掉了。现在多线程环境中推荐使用jdk1.5通过的ConcurrentHashMap 效能比Hashtable高很多
4、数组容量
HashMap的初始化容量为16,HashMap的容量一定是2次幂,当容量不够的时候会扩容到当前容量的2倍。如果指定HashMap的容量不是2的次幂的时候,会扩容到2次幂.Hashtble的默认大小是11,扩容方式是 old * 2 + 1
5、Hash值的使用不同
Hashtable直接使用对象提供的hashCode,而HashMap重写计算hash值。
6、迭代
1、 Hashtable、HashMap都使用了 Iterator。HashMap的迭代器是fail-fat迭代器,当迭代HashMap时如果其他线程修改了HashMap的结构那么就会抛出ConcurrentModificationException。但Iterator的remove方法不会抛出异常。但这并不是一个一定发生的行为,要看JVM,
2、JDK1.8以前Hashtable用的迭代器还不是 fail-fat跌打去。jdk1.8以后用的就是fail-fat迭代器了
3、当线程而由于历史原因,Hashtable还使用了Enumeration的方式 。下面就是HashTable通过枚举的方式遍历集合的所以value
Enumeration h = hashTable.elements(); while(h.hasMoreElements()) { System.out.println(h.nextElement()); }