HashMap和Hashtable的区别?
Java中的HashMap
和Hashtable
有什么区别?
哪种方法对非线程应用程序更有效?
Java中的HashMap
和Hashtable
有几个区别:
Hashtable
是同步的,而HashMap
不是。 这使得HashMap
对于非线程应用程序更好,因为非同步对象通常比同步对象执行得更好。
Hashtable
不允许null
键或值。 HashMap
允许一个null
键和任意数量的null
值。
其中一个HashMap的子类是LinkedHashMap
,所以如果您希望可预测的迭代顺序(默认为插入顺序),您可以轻松地将HashMap
替换为LinkedHashMap
。 如果你使用Hashtable
这不会那么容易。
由于同步不是你的问题,我建议HashMap
。 如果同步成为问题,您也可以查看ConcurrentHashMap
。
请注意,很多答案指出Hashtable是同步的。 在实践中,这种购买很少。 在访问器/增量器方法上的同步将停止两个线程同时添加或从地图中删除,但在现实世界中,您经常需要额外的同步。
一个非常常见的习惯用法是“检查然后放入” - 即在Map中查找一个条目,如果它尚不存在,则添加它。 无论您使用Hashtable还是HashMap,这都不是原子操作。
等价的同步HashMap可以通过以下方式获得:
Collections.synchronizedMap(myMap);
但要正确实现此逻辑,您需要对表单进行其他同步 :
synchronized(myMap) {
if (!myMap.containsKey("tomato"))
myMap.put("tomato", "red");
}
即使迭代Hashtable的条目(或由Collections.synchronizedMap获取的HashMap)也不是线程安全的,除非您还通过附加同步来防止修改映射。
ConcurrentMap接口的实现(例如ConcurrentHashMap)通过包含线程安全的check-then-act语义来解决其中的一些问题,例如:
ConcurrentMap.putIfAbsent(key, value);
没有人提到过Hashtable
不是Java Collections框架的一部分 - 它只是提供了一个类似的API。 另外, Hashtable
被认为是遗留代码。 没有什么能够使用HashMap
或派生的HashMap
来完成Hashtable
,因此对于新代码,我没有看到任何回到Hashtable
理由。