1.从类定义
这个从源代码中可以直接看出来,HashMap继承自AbstractMap,而HashTable继承自Dictionary。
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V> ,Cloneable,Serializable
public class HashTable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable,java.io.Serializable
2.从线程安全性
HashTable 在很多方法定义时都会加上synchronized关键字,说明HashTable是线程安全的,而HashMap并不能保证线程安全。
例如HashTable的如下方法都添加了synchronized关键字修饰,以确保其线程安全。
public synchronized int size();
public synchronized boolean isEmpty();
public synchronized boolean contains(Object o);
public synchronized V get(Object key);
public synchronized V put(K key,V value);
......
3.key和value是否允许null
从HashTable添加元素的源码中,我们可以发现,如果添加元素的value为null时,会抛出NullPointerException。在程序内部,有这样一行代码,int hash = key.hashCode,如果添加的key为null时,此时也会抛出空指针异常。因此,在HashTable中,是不允许key和value为null的。HashTable中key、value都不允许为null,否则会抛出NullPointerException异常。
而在HashMap的put方法中,调用了putVal方法(1.8版本中),该方法需要有一个int类型的Hash值,这个值是利用内部的Hash方法产生的。当key为null时,返回的Hash值为0,说明在hashMap中是允许key=null的情况存在。HashMap允许最多有一个key为null,允许有多个value为null。
4.是否提供contains()方法
从源码上看,HashMap中没有定义contains()方法;而HashTable中包含了contains()方法。
从HashMap提供的API中可以看出,它只包含containsKey和containsValue方法,而在HashTable中还包含了contains方法。
HashMap中把contains方法去掉的主要原因是它容易引起混淆,不如containsKey和containsValue表达得准确。而HashTable中contains方法也是调用containsKey方法来实现的。
public boolean contains(Object o){
return containsKey(o);
}
5.初始容量
HashTable在不指定容量的情况下的默认容量为11,而HashMap为16,Hashtable不要求底层数组的容量一定要为2的整数次幂,而HashMap则要求一定为2的整数次幂。
6、HashTable已经配淘汰:
如果是单线程情况下建议使用HashMap,如果是多线程的情况下建议使用ConcurrentHashMap,此处可表明HashTable自己都不建议使用自己。