LinkedHashMap的内部实现与HashMap实现有何不同?

Mer*_*ary 25 java hashmap linkedhashmap

我读到HashMap具有以下实现:

main array 
   ?
[Entry] ? Entry ? Entry      ? linked-list implementation
[Entry]
[Entry] ? Entry
[Entry]
[null ]
Run Code Online (Sandbox Code Playgroud)

因此,它有一个Entry对象数组.

问题:

  1. 我想知道如果相同的hashCode但不同的对象,这个数组的索引如何存储多个Entry对象.

  2. 这与LinkedHashMap实施有何不同?它是map的双链表实现,但它是否像上面那样维护一个数组,它如何存储指向下一个和前一个元素的指针?

Ank*_*tal 60

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;
     }
  }
Run Code Online (Sandbox Code Playgroud)

通过使用之前和之后 - 我们在LinkedHashMap中跟踪新添加的条目,这有助于我们维护插入顺序.

在引用之前的条目之前和之后引用LinkedHashMap中的下一个条目.

LinkedHashMap的

有关图表和分步说明,请参阅http://www.javamadesoeasy.com/2015/02/linkedhashmap-custom-implementation.html

谢谢..!!

  • 该图是方便的东西,更精细. (8认同)
  • @GurinderSPanesar如果你仔细观察上面的图表.'next'是指向相同存储桶列表中的下一个条目的指针(更具体地说,具有相同的散列码)''是'按照插入顺序指向下一个条目的指针. (2认同)
  • 图表和参考链接非常有用. (2认同)
  • 由此证明。一幅图片大于一千个单词。感谢分享。 (2认同)

Ste*_*n C 44

所以,它有一个Entry对象数组.

不完全是.它有一系列Entry对象.一个HashMap.Entry对象有一个next字段,允许Entry对象被链接的链接列表.

我想知道Entry如果相同的hashCode但不同的对象,这个数组的索引如何存储多个对象.

因为(如问题中的图片所示)Entry对象被链接.

这与LinkedHashMap实施有何不同?它是map的双链表实现,但它是否像上面那样维护一个数组,它如何存储指向下一个和前一个元素的指针?

LinkedHashMap实现中,LinkedHashMap.EntryHashMap.Entry通过添加beforeafter字段来扩展类.这些字段用于将LinkedHashMap.Entry对象组装到记录插入顺序的独立双向链表中.因此,在LinkedHashMap类中,条目对象位于两个不同的链中:

  • 通过主哈希数组访问的单链接哈希链,和

  • 在条目插入顺序中保留的所有条目的单独双向链接列表.


Ste*_* P. 11

快来看看自己.为了将来参考,你可以谷歌:

java LinkedHashMap源码

HashMap使用LinkedList来处理collissions,但之间的差HashMap并且LinkedHashMapLinkedHashMap具有可预测迭代顺序,这是通过一个额外的双链表,这通常保持键的插入顺序来实现的.例外情况是重新插入密钥时,在这种情况下它会返回到列表中的原始位置.

作为参考,迭代a LinkedHashMap比迭代a 更有效HashMap,但LinkedHashMap内存效率更低.

如果从我上面的解释中不清楚,散列过程是相同的,那么你可以获得普通散列的好处,但是你也可以获得上面所述的迭代优势,因为你使用了一个双向链表来保持Entry对象的顺序,这与在冲突的哈希过程中使用的链表无关,如果不明确的话.

编辑:(响应OP的评论):
A HashMap由数组支持,其中一些插槽包含Entry处理冲突的对象链.要遍历所有(键,值)对,您需要遍历数组中的所有插槽然后通过LinkedLists; 因此,您的总时间将与容量成比例.

使用a时LinkedHashMap,您需要做的只是遍历双向链表,因此总时间与大小成正比.

  • 有人可以解释一下downvote.我在这里说的都不正确. (3认同)
  • 我没有拒绝这个答案.为了记录,我决定自己编写,因为我认为你的问题没有直接解决OP的问题*,并没有真正解释实现细节. (3认同)
  • @aaronman - 你能做到的.但这不是"它完成"的方式.如果你"干涉"他们的答案,人们可​​能会被冒犯.(我很少这样做......当我看到一个被接受的答案是危险的错误.) (3认同)
  • 我也买了一个,我打赌那个刚回答的那个人 (2认同)
  • @aaronman这不是关于代表,而是关于提供最好的答案.他的回答看起来很好,比我的更清楚.不以任何方式解释随机的downvote,但是,这不是他的行为... (2认同)