协慌网

登录 贡献 社区

HashMap 和 Hashtable 之间的区别?

Java 中的HashMapHashtable有什么区别?

哪个非线程应用程序更有效?

答案

Java 中的HashMapHashtable有几点不同:

  1. Hashtable同步的 ,而HashMap则不是。这使得HashMap更适合非线程应用程序,因为非同步对象通常比同步对象执行得更好。

  2. Hashtable不允许使用null键或值。 HashMap允许一个null键和任意数量的null值。

  3. HashMap 的子类之一是LinkedHashMap ,因此如果您想要可预测的迭代顺序(默认情况下是插入顺序),您可以轻松地为LinkedHashMap换出HashMap 。如果您使用Hashtable这将不那么容易。

由于同步对您来说不是问题,我建议使用HashMap 。如果同步成为问题,您还可以查看ConcurrentHashMap

请注意,许多答案表明 Hashtable 已同步。 在实践中,这很少给你买。访问器 / mutator 方法上的同步将阻止两个线程同时添加或从地图中删除,但在现实世界中,您经常需要额外的同步。

一个非常常见的习语是 “检查然后放” - 即在 Map 中查找条目,如果它尚不存在则添加它。无论您使用 Hashtable 还是 HashMap,这都不是原子操作。

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

Collections.synchronizedMap(myMap);

但要正确实现此逻辑,您需要额外的表单同步

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

即使迭代 Hashtable 的条目(或 Collections.synchronizedMap 获得的 HashMap)也不是线程安全的,除非您还通过其他同步保护 Map 不被修改。

ConcurrentMap接口的实现(例如ConcurrentHashMap )通过包含线程安全的 check-then-act 语义来解决其中的一些问题,例如:

ConcurrentMap.putIfAbsent(key, value);

Hashtable被视为遗留代码。有没有什么关于Hashtable不能用做HashMap或派生HashMap ,因此对于新的代码,我看不出有任何理由要回Hashtable