Java中的 HashMap 和 Hashtable 有什么区别?

问题

Java中的HashMapHashtable有什么区别?

哪种方法对非多线程应用程序更有效?


#1 热门回答(3173 赞)

Java中的HashMapHashtable有几个区别:

  • Hashtable 是同步的,而HashMap不是。这使得 HashMap 对于非线程应用程序更好,因为非同步对象通常比同步对象执行得更好。
  • Hashtable` 不允许空键或值。 HashMap允许一个空键和任意数量的空值。
  • HashMap的一个子类是 LinkedHashMap,所以如果你想要可预测的迭代顺序(这是默认的插入顺序),你可以很容易地换出一个LinkedHashMap的HashMap。如果你使用Hashtable,这不会那么容易。

由于同步不是你的问题,我建议HashMap。如果同步成为问题,你也可以看看ConcurrentHashMap


#2 热门回答(575 赞)

请注意,很多答案都指出Hashtable是同步的.**实际上这很少会用。**在访问器/增量器方法上的同步将停止两个线程同时添加或从 Map 中删除,但在现实世界中,您经常需要额外的同步。

一个非常常见的习惯用法是“检查然后放入”

  • 即在地图中查找条目,如果它尚不存在,则添加它。无论您使用Hashtable还是HashMap,这都不是原子操作。

等价的同步HashMap可以通过以下方式获得:

Collections.synchronizedMap(myMap);

但要正确实现此逻辑,您需要附加同步的形式:

synchronized(myMap) {
    if (!myMap.containsKey("tomato"))
        myMap.put("tomato", "red");
}

即使迭代Hashtable的条目(或由Collections.synchronizedMap获取的HashMap)也不是线程安全的,除非您还通过附加同步来防止修改映射。

ConcurrentMap接口的实现(例如,ConcurrentHashMap)通过包含线程安全检查 - 然后动作语义来解决其中的一些问题,例如:

ConcurrentMap.putIfAbsent(key, value);

#3 热门回答(287 赞)

没有人提到“Hashtable”不是Java集合框架的一部分 - 它只是提供了一个类似的API。“Hashtable”被认为是遗留代码。没有什么关于Hashtable不能用HashMap或者HashMap派生来完成,所以对于新代码,我没有看到回到Hashtable的任何理由。