HashMap和Hashtable的区别?

Java中的HashMapHashtable有什么区别?

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

Java中的HashMap和Hashtable有几个区别:

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

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

  3. 其中一个HashMap的子类是LinkedHashMap ,所以如果你想要可预测的迭代顺序(这是默认的插入顺序),你可以很容易地换出一个LinkedHashMapHashMap 。 如果你使用Hashtable这将不那么容易。

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

请注意,很多答案指出Hashtable是同步的。 在实践中,这很less买你。 在访问器/增量器方法上的同步将停止两个线程同时添加或从地图中删除,但在现实世界中,你经常需要额外的同步。

一个非常常见的习惯用法是“检查然后放置” – 即在地图中查找一个条目,如果它尚不存在,则添加它。 无论使用Hashtable还是HashMap,这都不是primefaces操作。

等价的同步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 不是 Java集合框架的一部分 – 它只是提供了一个类似的API。 而且, Hashtable被认为是遗留代码。 没有什么能够使用HashMapHashMap派生无法完成的Hashtable ,所以对于新的代码,我没有看到任何回到Hashtable理由。

这个问题经常在面试中被问到是否候选人理解收集类的正确使用,并知道可用的替代解决scheme。

  1. HashMap类大致等同于Hashtable,不同之处在于它不是同步的并且允许空值。 (HashMap允许空值作为键和值,而Hashtable不允许空值)。
  2. HashMap不能保证地图的顺序会随着时间的推移保持不变。
  3. HashMap是非同步的,而Hashtable是同步的。
  4. HashMap中的迭代器是安全的,而Hashtable的枚举器不是,并且如果其他任何线程通过添加或除去Iterator自身的remove()方法之外的任何元素来修改映射,则抛出ConcurrentModificationException。 但是,这不是一个有保证的行为,并将尽最大努力由JVM完成。

关于一些重要条款的说明

  1. 同步意味着只有一个线程可以在一个时间点修改一个哈希表。 基本上,这意味着在执行哈希表更新之前,任何线程都必须获取对象上的锁,而其他人将等待锁释放。
  2. Fail-safe与迭代器的上下文相关。 如果在集合对象上创build了一个迭代器,并且某个其他线程尝试从“结构上”修改集合对象,则会引发并发修改exception。 其他线程可能调用“set”方法,因为它不会“结构性”地修改集合。 但是,如果在调用“set”之前,集合已经在结构上进行了修改,则会抛出“IllegalArgumentException”exception。
  3. 结构修改意味着删除或插入可有效改变地图结构的元素。

HashMap可以被同步

Map m = Collections.synchronizeMap(hashMap);

Map提供Collection视图,而不是直接支持通过Enumeration对象进行迭代。 集合视图大大提高了界面的performance力,这在本节后面讨论。 Map允许迭代键,值或键值对; 散列表不提供第三个选项。 Map提供了一个安全的方法来删除迭代中的条目; 哈希表没有。 最后,Map修复了Hashtable接口中的一个小缺陷。 Hashtable有一个叫做contains的方法,如果Hashtable包含给定的值,则返回true。 考虑到它的名字,如果Hashtable包含一个给定的键,那么你会希望这个方法返回true,因为这个键是Hashtable的主要访问机制。 Map接口通过重命名方法containsValue消除了这个混淆的来源。 此外,这提高了界面的一致性 – containsValue类似containsKey。

地图界面

请记住,在引入Java集合框架(JCF​​)之前, HashTable是遗留类,后来被改进以实现Map接口。 VectorStack

因此,在其他代码中总会有更好的select,因此在新的代码中总是远离它们

这里是你会发现有用的Java集合备忘单 。 注意灰色块包含遗留类HashTable,Vector和Stack。

在这里输入图像描述

HashMap :使用散列码来索引数组的Map接口的实现。 Hashtable :你好,1998年。 他们希望他们的收集API回来。

但是严重的是,你最好不要使用Hashtable 。 对于单线程应用程序,您不需要额外的同步处理开销。 对于高度并发的应用程序,偏执同步可能会导致饥饿,死锁或不必要的垃圾收集暂停。 像Tim Howland指出的那样,你可以使用ConcurrentHashMap来代替。

除了什么izb说, HashMap允许空值,而Hashtable不。

另请注意, Hashtable扩展了Dictionary类,它作为Javadocs状态已经过时,并被Map接口所取代。

看看这个图表。 它提供了不同的数据结构与HashMap和Hashtable之间的比较。 比较是精确的,清晰的,易于理解的。

Java集合matrix

HashtableHashMap类似,具有类似的接口。 除非需要对传统应用程序的支持,否则build议使用HashMap ,否则需要同步,因为Hashtables方法是同步的。 所以在你的情况,因为你不是multithreading, HashMaps是你最好的select。

散列表和散列表之间的另一个主要区别是,HashMap中的Iterator是快速失​​败的,而Hashtable的枚举符则不是,并且如果任何其他线程通过添加或删除除Iterator自身的remove()方法之外的任何元素来修改映射,则抛出ConcurrentModificationException。 但是,这不是一个有保证的行为,而是由JVM尽最大努力完成的。“

我的来源: http : //javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html

除了这里已经提到的所有其他重要方面之外,Collections API(例如Map接口)也一直在进行修改,以符合对Java规范的“最新和最好的”补充。

例如,比较Java 5 Map迭代:

 for (Elem elem : map.keys()) { elem.doSth(); } 

与旧的Hashtable方法相比:

 for (Enumeration en = htable.keys(); en.hasMoreElements(); ) { Elem elem = (Elem) en.nextElement(); elem.doSth(); } 

在Java 1.8中,我们也承诺能够像旧的脚本语言一样构build和访问HashMap:

 Map<String,Integer> map = { "orange" : 12, "apples" : 15 }; map["apples"]; 

更新:不,他们不会在1.8 …

Project Coin的集合增强function将在JDK8中进行吗?

  • HashTable是同步的,如果你在一个线程中使用它,你可以使用HashMap ,它是一个非同步的版本。 不同步的对象往往更高效一些。 顺便说一下,如果多个线程同时访问HashMap,并且至less有一个线程在结构上修改了映射,则它必须在外部同步。 Youn可以使用下面的代码封装一个同步的地图:

     Map m = Collections.synchronizedMap(new HashMap(...)); 
  • HashTable只能包含非null对象作为键或值。 HashMap可以包含一个空键和空值。

  • 由Map返回的迭代器是快速失败的,如果迭代器创build后随时都可以在结构上修改映射,除了通过迭代器自己的remove方法以外,迭代器将抛出ConcurrentModificationException 。 因此,在并发修改的情况下,迭代器快速而干净地失败,而不是在未来的未定的时间冒着任意的,不确定的行为冒险。 Hashtable的键和元素方法返回的枚举不是快速失败的。

  • HashTable和HashMap是Java Collections Framework的成员(自Java 2平台v1.2以来,HashTable被改进以实现Map接口)。

  • HashTable被认为是遗留代码,如果需要线程安全高度并行的实现,文档build议使用ConcurrentHashMap代替Hashtable。

  • HashMap不保证元素返回的顺序。 对于HashTable我猜这是一样的,但我不完全确定,我没有find明确说明的资源。

HashMapHashtable也有显着的algorithm差异。 之前没有人提到过这个,所以我才把它提出来。 HashMap将构造一个具有两个尺寸幂的散列表,dynamic增加它,使得在任何存储桶中至多有八个元素(冲突),并且对于一般元素types将非常好地搅动元素。 然而,如果你知道你在做什么, Hashtable实现提供了更好更好的哈希控制,也就是说,你可以使用例如最接近你的值域大小的素数来修复表的大小,这将导致比HashMap更好的性能,即更less一些情况下的碰撞。

除了在这个问题上广泛讨论的显而易见的区别之外,我将Hashtable看作是一个“手动驱动”的汽车,您可以更好地控制散列和HashMap作为一般性能良好的“自动驾驶”对象。

哈希表是同步的,而哈希表不是。 这使得Hashtable比Hashmap慢。

对于非线程应用程序,使用HashMap,因为它们在function上是相同的。

Java中HashMapHashtable的区别:

1)线程安全

  • HashTable是内部同步的。
  • 因此,在multithreading应用程序中使用HashTable是非常安全的。
  • HashMap不在内部同步的地方。
  • 因此,在没有外部同步的情况下,在multithreading应用程序中使用HashMap是不安全的。
  • 您可以使用Collections.synchronizedMap()方法从外部同步HashMap。

2)inheritance自

  • 虽然HashMap和HashTable都实现了Map接口,但它们扩展了两个不同的类。
  • HashMap扩展了AbstractMap类,其中HashTableinheritance了java中遗留类的Dictionary类。

3)空键和空值

  • HashMap允许最多一个空键和任意数量的空值。
  • HashTable甚至不允许单个空键和空值。

4)遍历

  • HashMap只返回用于遍历HashMap元素的迭代器。
  • HashTable返回Iterator以及Enumeration,它可以用来遍历HashTable的元素。

5)失效 – 快速与失效 – 安全

  • 由HashMap返回的迭代器本质上是快速失败的,即如果在迭代器自身的remove()方法以外的Iterator创build之后修改了HashMap,则抛出ConcurrentModificationExceptionexception。
  • 另一方面,由HashTable返回的Enumeration本质上是自动防故障的,即如果在创buildEnumeration之后修改了HashTable,它们不会抛出任何exception。

6)性能

  • 由于HashTable是内部同步的,这使得HashTable比HashMap稍慢。

7)遗产类

  • HashTable是一个遗留类。
  • 几乎认为这是贬值的原因。
  • 从JDK 1.5开始,ConcurrentHashMap被认为是比HashTable更好的select。

8)Java Collection框架的成员

  • HashMap是在JDK 1.2中引入之初的Java Collection Framework的成员。
  • 但是,HashTable在JDK 1.2之前。 从JDK 1.2开始,实现了Map接口,使之成为集合框架的一员。

散列表和散列表之间的区别

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

  • 哈希表是同步的,而哈希表不是。

  • 这使得HashMap对于非线程应用程序更好,因为非同步对象通常比同步对象执行得更好。

根据这里的信息,我build议使用HashMap。 我认为最大的好处是Java会阻止你在迭代它时修改它,除非你通过迭代器来完成。

对于线程应用程序,您通常可以使用ConcurrentHashMap – 取决于您的性能要求。

HashMap和HashTable / HashMap vs HashTable之间的区别

  1. 同步或线程安全:这是两者之间最重要的区别。 HashMap是非同步的,不是线程安全的。另一方面,HashTable是线程安全和同步的。 何时使用HashMap? 答案是如果您的应用程序不需要任何multithreading任务,换句话说hashmap对于非线程应用程序更好。 应该在multithreading应用程序中使用HashTable。

  2. 空键和空值:Hashmap允许一个空键和任意数量的空值,而Hashtable不允许HashTable对象中的空键和空值。

  3. 迭代值:使用迭代器迭代Hashmap对象值.HashTable是除了使用枚举器遍历HashTable对象值的向量之外唯一的类。

  4. 失败快速迭代器:Hashmap中的迭代器是快速迭代器,而Hashtable的枚举器则不是。 根据Oracle Docs,如果在迭代器以任何方式创build之后(除了迭代器自己的remove方法),在任何时候结构修改Hashtable,那么迭代器将抛出ConcurrentModificationException。 结构修改意味着从Collection对象(这里是散列表或散列表)添加或删除元素。 因此,Hashtable键和元素方法返回的枚举不会失败快。我们已经解释了迭代器和枚举之间的区别。

  5. 性能:HashMap比前者更加快速并且使用的内存less于Hashtable。 与单线程环境中的Hashtable等同步对象相比,非同步对象的性能通常要好得多。

  6. 超类和传统:Hashtable是Dictionary类的一个子类,现在已经在Jdk 1.7中被淘汰了,所以它不再被使用了。 最好是外部同步HashMap或使用ConcurrentMap实现(例如ConcurrentHashMap).HashMap是AbstractMap类的子类。 尽pipeHashtable和HashMap具有不同的超类,但它们都是“Map”抽象数据types的实现。

已经发布了很多很好的答案。 我添加了几个新点并对其进行总结。

HashMapHashtable都用于以键和值forms存储数据 。 两者都使用哈希技术来存储唯一的密钥。 但是下面给出了HashMap和Hashtable类之间的区别。

HashMap中

1) HashMap是不同步的。 它不是线程安全的,不能在许multithreading之间共享,没有适当的同步代码。
2) HashMap允许一个空键和多个空值。
3) HashMap是JDK 1.2中引入的一个新类。
4) HashMap速度很快。
5)通过调用这个代码,我们可以使HashMap同步
Map m = Collections.synchronizedMap(HashMap);
6) HashMap被Iterator遍历。
7) HashMap迭代器是快速失败的。
8) HashMapinheritanceAbstractMap类。

哈希表

1) Hashtable是同步的。 它是线程安全的,可以与许multithreading共享。
2) Hashtable不允许任何空键或值。
3) Hashtable是一个传统的类。
4) Hashtable很慢。
5) Hashtable是内部同步的,不能不同步。
6) Hashtable由Enumerator和Iterator遍历。
7) Hashtable枚举器不是快速失败的。
8) HashtableinheritanceDictionary类。

更多阅读Java中的HashMap和Hashtable有什么区别?

在这里输入图像描述

除了已经提到的差异之外,应该注意的是,从Java 8开始, HashMapdynamic地用TreeNodes(红黑树)replace每个桶中使用的节点(链表),所以即使存在高散列冲突,最坏的情况当search

O(log(n))用于Hashtable HashMap Vs O(n)。

*上述改进尚未应用于Hashtable ,但仅适用于HashMapLinkedHashMapConcurrentHashMap

仅供参考,目前,

  • TREEIFY_THRESHOLD = 8 :如果一个桶包含8个以上的节点,链表将被转换成平衡树。
  • UNTREEIFY_THRESHOLD = 6 :当一个桶变得太小(由于移除或resize)树被转换回链接列表。

与HashTable和HashMaps有5个基本的区别。

  1. 地图允许您迭代和检索键,值和键值对,其中HashTable不具备所有这些function。
  2. 在Hashtable中有一个函数contains(),这是非常容易使用的。 因为含义的含义稍有偏差。 是否意味着包含密钥或包含值? 很难理解。 在Maps中我们有ContainsKey()和ContainsValue()函数,这很容易理解。
  3. 在hashmap中,可以安全地迭代时删除元素。 因为它不可能在哈希表中。
  4. HashTables默认是同步的,所以它可以很容易地用于多个线程。 HashMap在默认情况下不是同步的,因此只能用于单线程。 但是仍然可以使用Collections util类的synchronizedMap(Map m)函数将HashMap转换为同步。
  5. HashTable将不允许空键或空值。 HashMap允许一个空键和多个空值。

1. HashmapHashTable都存储键和值。

2. Hashmap可以存储一个键为nullHashtable不能存储null

3. HashMap不同步,但Hashtable是同步的。

4. HashMap可以与Collection.SyncronizedMap(map)同步

 Map hashmap = new HashMap(); Map map = Collections.SyncronizedMap(hashmap); 

我的小小贡献:

  1. HashtableHashMap之间的第一个和最显着的不同之处在于, HashMap不是线程安全的,而Hashtable是一个线程安全的集合。

  2. HashtableHashMap之间的第二个重要区别是性能,因为HashMap不同步,它比Hashtable更好。

  3. HashtableHashMap第三个区别是Hashtable是过时的类,您应该使用ConcurrentHashMap来代替Java中的Hashtable

HashTable是jdk中不应该使用的遗留类。 用ConcurrentHashMapreplace它的用法。 如果您不需要线程安全性,请使用HashMap ,它不是线程安全的,但速度更快,占用的内存也更less。

1)哈希表是同步的,而哈希表不是。 2)另一个区别是HashMap中的迭代器是安全的,而Hashtable的枚举器则不是。 如果在迭代过程中更改地图,则会知道。

3)HashMap允许空值,而Hashtable不允许。

HashMap: – 它是java.util包中的一个类,用于存储key和value格式的元素。

哈希表:这是一个正在被收集框架认可的遗留类

HashMap和HashTable

  • 关于HashMap和HashTable的一些要点。 请阅读下面的细节。

1)Hashtable和Hashmap实现java.util.Map接口2)Hashmap和Hashtable都是基于哈希的集合。 并在哈希工作。 所以这些是HashMap和HashTable的相似之处。

  • HashMap和HashTable有什么区别?

1)第一个区别是HashMap不是线程安全的而HashTable是ThreadSafe
2)HashMap性能更好,因为它不是线程安全的。 而Hashtable性能明智并不好,因为它是线程安全的。 所以多个线程不能同时访问Hashtable。

HashMaps给你自由的同步和debugging更容易

HashMap是模拟的,因此可用于GWT client codeHashtable则不是。

HashMap是一个用于存储键和值格式的元素的类,它不是线程安全的。 因为它不同步,因为Hashtable是synchronized.Hashmap允许为null,但hastable不允许为null。