4. Java中的HashMap和Hashtable有什么区别?| Java Debug 笔记

本文正在参加「Java主题月 – Java Debug笔记活动」,详情查看<活动链接>

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

Java中的HashMap和Hashtable有什么区别?对于单线程应用,哪一个更有效?

回答1:

HashMap和Hashtable在Java中有一些区别:

Hashtable是支持并发的,而HashMap不是。这HashMap对于单线程应用程序更好,因为非同步对象通常比同步对象执行得更好。

Hashtable不允许null作为键或值。 HashMap允许一个null键和任意数量的null值。

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

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

回答1下一个评论:

如果要使HashMap成为线程安全的,请使用Collections.synchronizedMap()。

回答2:
Hashtable被认为是遗留代码。没有任何事情是需要使用Hashtable但是无法使用HashMap来完成的,因此对于新代码,我看不出任何理由去使用Hashtable。

回答3:

注意,很多答案都说明Hashtable已同步。 在实践中,这几乎不会给您带来什么好处。 同步在访问器/更改器方法上将停止同时从映射中添加或删除两个线程,但是在现实世界中,您经常需要进行额外的同步。

一种非常常见的习惯用法是“先检查后放”-即在地图中查找条目,如果条目尚不存在,则将其添加。无论您使用Hashtable还是HashMap,这都不是原子操作。

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

Collections.synchronizedMap(myMap);
复制代码

但是要正确实现此逻辑,您需要对表单进行额外的同步:

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

甚至迭代Hashtable(或由Collections.synchronizedMap获得的HashMap)也不是线程安全的,除非您还防止通过附加同步来修改Map。

ConcurrentMap接口的实现(例如ConcurrentHashMap)通过包含线程安全的“先检查后行为”语义来解决其中的一些问题,例如:

ConcurrentMap.putIfAbsent(key, value);
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享