Java LinkedHashMap的实现与HashMap有何不同?

Java LinkedHashMap的实现与HashMap有何不同?,java,hashmap,complexity-theory,linkedhashmap,Java,Hashmap,Complexity Theory,Linkedhashmap,如果LinkedHashMap的时间复杂度与HashMap的复杂度相同,为什么我们需要HashMap?与Java中的HashMap相比,LinkedHashMap有哪些额外开销?LinkedHashMap将占用更多内存。普通HashMap中的每个条目都只有键和值。每个LinkedHashMap条目都有这些引用以及对下一个和上一个条目的引用。还有一点家务活要做,尽管这通常是无关紧要的。 LinkedHashMap还维护一个贯穿其所有条目的双链接列表,该列表将提供可复制的顺序。此链表定义了迭代顺序,

如果LinkedHashMap的时间复杂度与HashMap的复杂度相同,为什么我们需要HashMap?与Java中的HashMap相比,LinkedHashMap有哪些额外开销?

LinkedHashMap将占用更多内存。普通
HashMap
中的每个条目都只有键和值。每个
LinkedHashMap
条目都有这些引用以及对下一个和上一个条目的引用。还有一点家务活要做,尽管这通常是无关紧要的。

  • LinkedHashMap还维护一个贯穿其所有条目的双链接列表,该列表将提供可复制的顺序。此链表定义了迭代顺序,通常是将关键帧插入贴图的顺序(插入顺序)
  • HashMap没有这些额外的成本(运行时、空间),当您不关心插入顺序时,应该优先选择它而不是LinkedHashMap

LinkedHashMap是一种有用的数据结构,当您需要知道键在映射中的插入顺序时。一个合适的用例用于实现LRU缓存。由于LinkedHashMap的顺序维护,与HashMap相比,数据结构需要额外的内存。如果插入顺序不是必需的,您应该始终使用HashMap

如果LinkedHashMap的时间复杂度与HashMap的复杂度相同,为什么我们需要HashMap

您不应该混淆复杂性和性能。两种算法可能具有相同的复杂性,但其中一种算法的性能始终优于另一种算法

请记住,
f(N)是O(N)
表示:

limit(f(N), N -> infinity) <= C*N  

limit(f(N),N->infinity)HashMap和LinkedHashMap之间还有一个主要区别:对于LinkedHashMap,迭代更有效。

由于LinkedHashMap中的元素相互连接,因此迭代需要与贴图大小成比例的时间,而不管其容量如何。 但是如果是HashMap;因为并没有固定的顺序,所以在它上面的迭代需要与它的容量成比例的时间

我已经在我的网站上添加了更多详细信息。

  • 重新调整大小的速度应该会更快,因为它会遍历 用于将内容传输到新表数组的双链接列表
  • containsValue()被重写以利用更快的 迭代器
  • LinkedHashMap还可用于创建LRU缓存。特殊的 LinkedHashMap(容量、加载因子、accessOrderBoolean)构造函数 用于创建其迭代顺序为的链接哈希映射 上次访问其条目的顺序,从 最近访问次数最少,最近访问次数最多。在这种情况下,仅仅 使用get()查询映射是一种结构性修改

LinkedHashMap继承HashMap,这意味着它使用HashMap的现有实现在节点(Entry对象)中存储键和值。除此之外,它还存储一个单独的双链表实现,以保持输入键的插入顺序

看起来是这样的:

标题节点节点节点1节点2节点3节点4标题节点

所以额外的重载是在这个双链接列表中保持插入和删除。
好处是:迭代顺序保证为插入顺序,这不在HashMap中

HashMap
不维护插入顺序,因此不维护任何双链接列表

LinkedHashMap
最显著的特点是它维护键值对的插入顺序
LinkedHashMap
使用双链接列表进行此操作

LinkedHashMap
的条目如下所示:

  static class Entry<K, V> {
     K key;
     V value;
     Entry<K,V> next;
     Entry<K,V> before, after;        //For maintaining insertion order    
     public Entry(K key, V value, Entry<K,V> next){
         this.key = key;
         this.value = value;
         this.next = next;
     }
  }
静态类条目{
K键;
V值;
进入下一步;
输入before,after;//用于维护插入顺序
公共输入(K键、V值、下一个输入){
this.key=key;
这个值=值;
this.next=next;
}
}
通过使用before和after-我们跟踪
LinkedHashMap
中新添加的条目,这有助于我们维护插入顺序

请参阅之前的条目和 after指的是
LinkedHashMap
中的下一个条目


有关图表和分步说明,请参考

,因此,与HashMap相比,性能稍低。@Jon Skeet如果LinkedHashMap包含对上一个和下一个值的额外引用,则删除或插入任何项都会为重新连接带来额外成本?如果我得到完整的实现,或者有链接,或者有解释,那就太好了。@热情的程序员:源代码是公开的-为什么不看看呢?是的,插入和删除确实需要更新链表。@我不是Java程序员,我不知道在哪里可以找到它:(。@StinePike:在行为上是有区别的,但在查找、添加项目等所花费的时间上,它们大致相当。(就复杂性而言,常数因子可能略有不同。)我想你指的是迭代顺序?@MichaelDeardeuff你是对的,但答案通常是正确的,因为Deafolt的
迭代顺序=插入顺序。插入顺序的可能替代方法是访问顺序。