Java中HashMap和Hashtable之间的区别是什么?
对于非线程应用程序,哪个更有效?
Java中HashMap和Hashtable之间的区别是什么?
对于非线程应用程序,哪个更有效?
当前回答
HashMap是一个用于以键和值格式存储元素的类。它不是线程安全的。因为它不同步。其中as Hashtable是同步的。Hashmap允许null,但hastable不允许null。
其他回答
同步或线程安全:
哈希映射不同步,因此不安全,如果没有适当的同步块,则无法在多个线程之间共享,而哈希表是同步的,因此是线程安全的。
空键和空值:
HashMap允许一个空键和任意数量的空值。Hashtable不允许空键或值。
迭代值:
HashMap中的迭代器是一个快速失败迭代器,而Hashtable的枚举器不是,如果任何其他线程通过添加或删除除迭代器自己的remove()方法之外的任何元素来修改映射结构,则抛出ConcurrentModificationException。
超级类和传统:
HashMap是AbstractMap类的子类,而Hashtable是Dictionary类的子级。
性能:
由于HashMap不同步,因此与Hashtable相比,它更快。
参考http://modernpathshala.com/Article/1020/difference-between-hashmap-and-hashtable-in-java有关Java集合的示例、面试问题和测验
HashTable是同步的,如果您在单个线程中使用它,则可以使用HashMap,这是一个未同步的版本。未同步的对象通常性能更高。顺便说一句,如果多个线程同时访问HashMap,并且至少有一个线程在结构上修改了该映射,那么它必须在外部同步。您可以使用以下方法将未同步的映射打包到已同步的映射中:Map m=Collections.synchronizedMap(新HashMap(…));HashTable只能包含非空对象作为键或值。HashMap可以包含一个空键和空值。Map返回的迭代器是快速失败的,如果在创建迭代器之后的任何时候对映射进行了结构修改,则除了通过迭代器自己的remove方法之外,迭代器将抛出ConcurrentModificationException。因此,在并发修改的情况下,迭代器会快速而干净地失败,而不是在未来某个不确定的时间冒着任意、非确定性行为的风险。而Hashtable的键和元素方法返回的枚举不会快速失败。HashTable和HashMap是Java集合框架的成员(自从Java 2平台v1.2以来,HashTable被改进以实现Map接口)。HashTable被认为是遗留代码,如果需要线程安全的高度并发实现,文档建议使用ConcurrentHashMap代替HashTable。HashMap不保证返回元素的顺序。对于HashTable,我想它是相同的,但我不完全确定,我找不到明确说明这一点的ressource。
请记住,HashTable是在引入Java集合框架(JCF)之前的遗留类,后来经过了修改以实现Map接口。Vector和Stack也是如此。
因此,在新代码中始终远离它们,因为正如其他人所指出的,JCF中总是有更好的替代方案。
这是Java集合备忘单,您会发现它很有用。请注意,灰色块包含旧类HashTable、Vector和Stack。
除了izb所说的,HashMap允许空值,而Hashtable不允许。
还要注意,Hashtable扩展了Dictionary类,作为Javadocs状态,该类已过时,已被Map接口取代。
注意,很多答案都表明Hashtable是同步的。在实践中,这几乎不会给你带来什么好处。同步是在访问器/赋值器上进行的。方法将停止同时从映射中添加或删除两个线程,但在现实世界中,您通常需要额外的同步。
一个非常常见的习惯用法是“先检查后放”,即在Map中查找条目,如果它不存在,则添加它。无论使用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);