Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么linkedhashmap为迭代维护双链表_Java_Performance - Fatal编程技术网

Java 为什么linkedhashmap为迭代维护双链表

Java 为什么linkedhashmap为迭代维护双链表,java,performance,Java,Performance,因为在任何线程中都没有内部和合理的解释。 请给我确切的理由 对于插入顺序,用单链表维护就足够了,但为什么不呢 在这种情况下,双链表如何提高性能 所有方法都继承自hashmap xpt 4方法,那么hashmap的迭代器不维护顺序,而linkedhashmap维护顺序 要保持插入顺序,有双链接列表。在任何时间点,都可以向前移动节点或向后移动节点。但若您使用的是单LinkedList,若指针移动到最后一个元素,则需要再次从初始点开始,并且不能在上一个节点上移动 LinkedHashMap基本上为每个

因为在任何线程中都没有内部和合理的解释。 请给我确切的理由

  • 对于插入顺序,用单链表维护就足够了,但为什么不呢

  • 在这种情况下,双链表如何提高性能

  • 所有方法都继承自hashmap xpt 4方法,那么hashmap的迭代器不维护顺序,而linkedhashmap维护顺序


  • 要保持插入顺序,有双链接列表。在任何时间点,都可以向前移动节点或向后移动节点。但若您使用的是单LinkedList,若指针移动到最后一个元素,则需要再次从初始点开始,并且不能在上一个节点上移动

    LinkedHashMap基本上为每个条目维护两个指针,即-: 之前、之后


    顾名思义,这两个指针都用于排序,并用于在插入或删除时调整指针。

    你说得对,你只需要维护一个单链表来跟踪插入顺序。但是为了有效地维护单链接列表,实际上需要一个双链接列表

    按顺序考虑三个条目

    A ---> B ---> C
    
    假设您删除了
    B
    。显然
    A
    现在应该指向
    C
    。但是,除非您知道
    B
    之前的条目,否则您无法有效地说哪个条目现在应该指向
    C
    。要解决此问题,需要条目指向两个方向

      --->   ---> 
    A      B      C
      <---   <---
    

    LinkedHashMap可用于维护插入顺序和访问顺序。 LinkedHashMap继承了hashmap在bucket中维护列表的相同功能,因此使用了next引用


    为了保持插入顺序,他们使用了双链表(在引用之前使用,在引用之后使用),但这可以通过使用单链表来实现。同时,他们必须实现访问顺序功能,因为他们需要频繁地将元素移动到末尾,并且需要频繁地删除以频繁地删除,所以他们使用了双链接列表。

    我还想补充一点,就是LinkedHashMap也可以通过设置其访问顺序来用作LRU缓存通过其构造函数将布尔值设置为true

    现在LinkedHashMap维护两个指针
    head
    (LinkedHashMap中最年长的)和
    tails
    (LinkedHashMap中最年轻的)。因此请记住,当您将accessOrder设置为true时,它将停止维护插入顺序,并开始像正确的LRU缓存一样运行


    现在,当LRU缓存超过其限制时,我们希望删除最早的条目,因为它在内部维护DoublyLinkedList,删除最早的条目相对较快,因为它维护两个指针(head和tails)它可以在两个方向上移动,或者我们可以说,如果它是一个用于删除最老条目的单链接列表,那么我们需要遍历所有节点,然后删除它。由于使用了指针
    head
    tails
    ,只需删除最后一个节点(最老的节点)即可轻松完成通过使用
    tails
    指针到达那里,并使用最后一个节点的上一个指针,在LinkedHashMap中创建双链接列表的第二个最后一个节点
    tail

    我不认为双链接列表有助于排序,它只会使遍历列表更容易,而不会使遍历更容易。它只会使删除映射项更有效。这样您就可以倒退。我不认为双链接列表有助于排序,它只会使遍历列表更容易,如果您看到HashMap内部是基于linkedList的。因此,如果您有诸如在之前或之后插入哪个节点之类的信息,那么这只是一个排序。一个单链表足以维持一个顺序。这并不是他们在这种情况下使用双链接列表的正确解释。应该注意的是,
    LinkedHashMap.keySet().iterator()
    返回一个普通的
    迭代器,而不是
    ListIterator
    。不能按相反的插入顺序迭代键。。。不考虑使用双链接列表的事实。API不允许这样做。简单明了。非常感谢!!现在我明白了为什么单链表是不够的。
    private void remove() {
        before.after = after;
        after.before = before;
    }