1.对外的接口不一致:HashTable比HashMap多提供elements和contains方法,elements()方法继承HashTable的父类dictionary。
public static void main(String[] args) {
Dictionary<String,String> dictionary = new Hashtable<>();
dictionary.put("e1","1");
dictionary.put("e2","2");
Enumeration<String> elements = dictionary.elements();
boolean contains = ((Hashtable<String, String>) dictionary).contains("3");
if (contains == false){
System.out.println(1);
}
}
2.对null的支持不一致:
HashTable:key和value都不能为null。(不能为空的原因与多线程挂钩)
HashMap:key可以为null,但这样的key只能有一个,因为必须保持key的唯一性,可以保持多个key拥有null值。hashMap存储的键如果是null将不会计算哈希值而是将他放入索引为0的位置。
补充:
HashTable的get方法查询一个不存在键时,HashTable返回null,如果允许键或者值为null,他将没法区别是键不存在还是其值为null。
3.安全性问题:
HashMap是线程不安全的,在多线程并发的环境下,可能会产生死锁等问题,因此需要开发人员自己处理多线程的安全问题。
HashTable是线程安全的,他的每个方法都有Synchronized关键字,因此可以直接用于多线程中。
虽然HashMap不安全但是大多数场景都是单线程的,所以效率高。
如果真的要使用线程安全的,我们会考虑使用ConcurrentHashMap虽然也是线程安全的,但是他的效率比HashTable要高很多倍,因为ConcurrentHashMap使用分段锁,并不对整个数据进行锁定。
HashTable只允许一个线程并发访问,对整个数据进行锁定。
尽管Hashtable提供了安全性,但他并不是最佳人选,因为整个对象的锁定可能导致性能瓶颈,他提供了更好的并发性能,因为它只锁定哈希表的某些部分(段或者分区),而不是整个哈希表。
4.初始容量和扩容大小不一样。