HashMap
和Hashtable
有什么区别?这是 Java / J2EE 专业人员常见的面试问题之一。HashMap
和Hashtable
这两个类实现了java.util.Map
接口,但它们的工作方式和用法存在差异。在这里,我们将讨论这些类之间的差异。
HashMap
vs Hashtable
1) HashMap
是非同步的。这意味着如果它在多线程环境中使用,那么多个线程可以同时访问和处理HashMap
。
Hashtable
已同步。它确保在给定时刻不超过一个线程可以访问Hashtable
。在Hashtable
上工作的线程获取一个锁,使其他线程等待,直到它的工作完成。
2)HashMap
允许一个空键和任意数量的空值。
Hashtable
不允许使用null
键和null
值。
3)HashMap
实现LinkedHashMap
维护插入顺序, TreeMap
根据键的升序对映射进行排序。
Hashtable
不保证任何顺序。它不以任何特定顺序维护映射。
4)最初Hashtable
不是集合框架的一部分,它在被改进以实现Map
接口之后成为了一个集合框架成员。
HashMap
实现了Map
接口,从一开始就是集合框架的一部分。
5)这些类之间的另一个区别是HashMap
的迭代器是一个快速失败并抛出ConcurrentModificationException
如果任何其他Thread
通过添加或删除除迭代器自己的remove()
方法之外的任何元素在结构上修改映射。简单来说,快速失败意味着:当调用iterator.next()
时,如果在创建迭代器和调用next()
的那一刻之间进行了任何修改,则立即抛出ConcurrentModificationException
。
Hashtable
的枚举器不是快速失败的。
对于例如
HashMap
:
HashMap hm= new HashMap();
....
....
Set keys = hm.keySet();
for (Object key : keys) {
//it will throw the ConcurrentModificationException here
hm.put(object & value pair here);
}
Hashtable:
Hashtable ht= new Hashtable();
....
.....
Enumeration keys = ht.keys();
for (Enumeration en = ht.elements() ; en.hasMoreElements() ; en.nextElement()) {
//No exception would be thrown here
ht.put(key & value pair here);
}
何时使用HashMap
和Hashtable
?
1)如上所述,HashMap
与Hashtable
是同步。如果需要线程安全操作,那么可以使用Hashtable
,因为它的所有方法都是同步的,但它应该是遗留类,应该避免,因为它没有任何关于它,HashMap
无法完成。对于多线程环境,我建议你使用ConcurrentHashMap
(几乎类似于 Hashtable),甚至可以使HashMap
显式同步。
2)同步操作性能较差,因此除非需要,否则应避免使用。因此,对于非线程环境,应该毫无疑问地使用HashMap
。