Java中HashMap和Hashtable之间的区别是什么?
对于非线程应用程序,哪个更有效?
Java中HashMap和Hashtable之间的区别是什么?
对于非线程应用程序,哪个更有效?
当前回答
面试中经常会问这个问题,以检查应聘者是否了解集合类的正确用法,并了解可用的替代解决方案。
HashMap类大致等同于Hashtable,只是它是非同步的并且允许为null。(HashMap允许空值作为键和值,而Hashtable不允许空值)。HashMap不能保证映射的顺序随时间保持不变。HashMap是非同步的,而Hashtable是同步的。HashMap中的迭代器是故障安全的,而Hashtable的枚举器不是,如果任何其他线程通过添加或删除迭代器自己的remove()方法以外的任何元素来从结构上修改映射,则引发ConcurrentModificationException。但这不是一种保证的行为,将由JVM尽最大努力完成。
关于一些重要条款的说明:
同步意味着只有一个线程可以在一个时间点修改哈希表。基本上,这意味着在对Hashtable执行更新之前,任何线程都必须获取对象的锁,而其他线程将等待释放锁。故障安全在迭代器的上下文中是相关的。如果在集合对象上创建了迭代器,并且其他线程试图“从结构上”修改集合对象,则将引发并发修改异常。但其他线程也可以调用set方法,因为它不会“从结构上”修改集合。但是,如果在调用set之前,集合已经在结构上进行了修改,则将抛出IllegalArgumentException。结构修改意味着删除或插入可以有效改变地图结构的元素。
HashMap可以通过
Map m=Collections.synchronizedMap(hashMap);
Map提供集合视图,而不是通过枚举对象直接支持迭代。集合视图极大地增强了界面的表现力,这将在本节稍后讨论。Map允许您遍历键、值或键值对;哈希表不提供第三个选项。Map提供了一种在迭代过程中删除条目的安全方法;哈希表没有。最后,Map修复了Hashtable接口中的一个小缺陷。Hashtable有一个名为contains的方法,如果Hashtable包含给定值,则返回true。给定它的名称,如果Hashtable包含给定的键,您会希望该方法返回true,因为该键是Hashtable的主要访问机制。Map接口通过重命名方法containsValue消除了这种混淆。此外,这提高了接口的一致性-containsValue与containsKey类似。
地图界面
其他回答
HashMap和Hashtable也有显著的算法差异。以前没有人提到过这一点,所以我才提出来。HashMap将构造一个大小为两倍的哈希表,动态地增加它,以便在任何bucket中最多有八个元素(冲突),并且对于一般的元素类型,可以很好地搅拌这些元素。然而,如果你知道你在做什么,Hashtable实现提供了对哈希的更好和更精细的控制,也就是说,你可以使用最接近你的值域大小的素数来固定表大小,这将导致比HashMap更好的性能,即在某些情况下更少的冲突。
除了在这个问题中广泛讨论的明显差异之外,我认为Hashtable是一款“手动驾驶”汽车,您可以更好地控制哈希,而HashMap是“自动驾驶”的对应车型,通常表现良好。
除了izb所说的,HashMap允许空值,而Hashtable不允许。
还要注意,Hashtable扩展了Dictionary类,作为Javadocs状态,该类已过时,已被Map接口取代。
Java中HashMap和Hashtable之间有几个不同之处:
Hashtable是同步的,而HashMap不是。这使得HashMap更适合非线程应用程序,因为非同步对象通常比同步对象执行得更好。哈希表不允许空键或值。HashMap允许一个空键和任意数量的空值。HashMap的子类之一是LinkedHashMap,因此,如果您需要可预测的迭代顺序(默认情况下是插入顺序),您可以很容易地将HashMap替换为LinkedHashMap。如果您使用Hashtable,这将不会那么容易。
由于同步对您来说不是问题,所以我推荐HashMap。如果同步成为问题,您还可以查看ConcurrentHashMap。
Hashtable与HashMap类似,具有类似的接口。建议您使用HashMap,除非您需要支持遗留应用程序或需要同步,因为Hashtable方法是同步的。因此,在您不是多线程的情况下,HashMaps是您的最佳选择。
面试中经常会问这个问题,以检查应聘者是否了解集合类的正确用法,并了解可用的替代解决方案。
HashMap类大致等同于Hashtable,只是它是非同步的并且允许为null。(HashMap允许空值作为键和值,而Hashtable不允许空值)。HashMap不能保证映射的顺序随时间保持不变。HashMap是非同步的,而Hashtable是同步的。HashMap中的迭代器是故障安全的,而Hashtable的枚举器不是,如果任何其他线程通过添加或删除迭代器自己的remove()方法以外的任何元素来从结构上修改映射,则引发ConcurrentModificationException。但这不是一种保证的行为,将由JVM尽最大努力完成。
关于一些重要条款的说明:
同步意味着只有一个线程可以在一个时间点修改哈希表。基本上,这意味着在对Hashtable执行更新之前,任何线程都必须获取对象的锁,而其他线程将等待释放锁。故障安全在迭代器的上下文中是相关的。如果在集合对象上创建了迭代器,并且其他线程试图“从结构上”修改集合对象,则将引发并发修改异常。但其他线程也可以调用set方法,因为它不会“从结构上”修改集合。但是,如果在调用set之前,集合已经在结构上进行了修改,则将抛出IllegalArgumentException。结构修改意味着删除或插入可以有效改变地图结构的元素。
HashMap可以通过
Map m=Collections.synchronizedMap(hashMap);
Map提供集合视图,而不是通过枚举对象直接支持迭代。集合视图极大地增强了界面的表现力,这将在本节稍后讨论。Map允许您遍历键、值或键值对;哈希表不提供第三个选项。Map提供了一种在迭代过程中删除条目的安全方法;哈希表没有。最后,Map修复了Hashtable接口中的一个小缺陷。Hashtable有一个名为contains的方法,如果Hashtable包含给定值,则返回true。给定它的名称,如果Hashtable包含给定的键,您会希望该方法返回true,因为该键是Hashtable的主要访问机制。Map接口通过重命名方法containsValue消除了这种混淆。此外,这提高了接口的一致性-containsValue与containsKey类似。
地图界面