由于在任何线程中都没有内部和合理的解释。 请给我确切的理由。
对于插入顺序,它足以维持单链表,但为什么不呢?
在这种情况下,双向链表如何提高性能?
所有方法都继承自hashmap xpt 4方法,然后hashmap的迭代器不维护顺序,而linkedhashmap维护顺序?
答案 0 :(得分:10)
你是对的,你只需要维护一个单链表来跟踪插入顺序。但是为了有效地维护单链表,你实际上需要一个双向链表。
按顺序考虑三个条目
A ---> B ---> C
假设您删除B
。显然,A
现在应指向C
。但除非您知道B
之前的条目,否则您无法有效地说明哪个条目现在指向C
。要解决此问题,您需要指向两个方向的条目。
---> --->
A B C
<--- <---
这样,当您移除B
时,您只需查看B
(A
和C
之前和之后的条目,然后更新{{1} }和A
指向对方。
C
保持广告订单的原因LinkedHashMap
没有,尽管除了4种方法之外的所有方法都是继承的,但是它写得非常巧妙。大多数特定于实现的操作都是HashMap
的成员,而不是HashMap.Entry
。 HashMap
有一个LinkedHashMap
班private static
,其扩展了LinkedHashMap.Entry
static
HashMap.Entry
个班级HashMap
。例如,当您致电put
或remove
时,LinkedHashMap
的代码可能与HashMap
的代码相同,因为它本身就是条目跟踪信息之前和之后的信息。例如,以下是我在上面解释的LinkedHashMap.Entry.remove()
的完整代码
private void remove() {
before.after = after;
after.before = before;
}
答案 1 :(得分:3)
LinkedHashMap基本上为每个条目维护两个指针 - : 之前,之后
如名称所示,这两个指针都用于排序目的,用于在插入或删除时调整指针。
答案 2 :(得分:1)
要维护广告订单,会有双重的LinkedList。在任何时候你都可以向前移动节点或向后节点。但是如果你的指针移动到最后一个元素,你有单个LinkedList,你再次需要从初始点开始,你不能移动到前一个节点。
答案 3 :(得分:0)
我还要补充的一点是LinkedHashMap也可以通过其构造函数将accessOrder boolean设置为true来用作LRU Cache。
现在,LinkedHashMap维护了两个指针head
(LinkedHashMap中最年长的)和tails
(最年轻的LinkedHashMap)。因此,请记住,当您将accessOrder设置为true时,它会停止维护插入顺序并开始表现得像正确的LRU缓存。
现在当LRU缓存超过其限制并且我们想要删除最老的条目时,因为它在内部维护DoublyLinkedList,删除最旧的条目相对较快,因为它保持两个指针(头部和尾部)可以在两个方向上移动或我们可以说,如果它是一个单一链接列表,用于删除最老的条目,我们需要遍历所有节点,然后删除它。感谢指针head
和tails
,可以通过在tails
指针的帮助下到达最后一个节点(最远的一个节点)并将最后一个节点的前一个指针移到那里来轻松完成LinkedHashMap中DoublyLinkedList的第二个节点tail
。
答案 4 :(得分:-1)
LinkedHashMap可用于维护广告订单和维护访问顺序。 LinkedHashMap继承了bucket中维护列表的hashmap的相同功能,因此使用 next 引用。
为了维护插入顺序,他们使用了双向链表(在之前使用,在之后使用),但这可以通过使用单链表来完成。同时,他们必须实现访问顺序功能,并且需要频繁移动元素到最后,并且需要频繁删除频繁删除,他们使用双向链表。