LinkedHashMap的相关问题

LinkedHashMa结构的话是直接继承HashMap的,其所有的方法除了几个回调的方法之外都是继承HashMap的方法来实现操作的。

1. LinkedHashMap与HashMap一样,底层都是数组+单链表+红黑树,扩容机制也是相同的

2. LinkedHashMap相比HashMap的拉链式存储结果,内部额外的通过静态类Entry维护了一个双向链表

3. HashMap元素的遍历顺序不一定和元素的插入顺序相同,但LinkedHashMap通过遍历获取元素的时候,遍历顺序在一定条件下等于插入顺序的

4. LinkedHashMap可以通过构造参数accessOrder来指定双向链表是否是元素访问后改变顺序。accessOrder为true的时候,表示此元素被访问需要调用AfterNodeAccess方法将当前元素移至链表最后。为false的时候表示插入AfterNodeInsertion()需要移除最老的元素removeEldestEntry(first),但是默认为false,可以通过重写这个方法来达到限定容量,当容量达到时移除最老的元素,一般默认为是当前头结点元素。

移除最老元素其实也是一种算法LRU(Least Recently Used)近期最少使用。大致实现就是当达到设定的一个阈值,阈值可能是内存不足或者是最大容量,找到最近使用的存储元素进行移除,以确保新添加的元素可以被保存到集合中。

    protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
        return false;
    }
  // 以下方法被官方注释起来了,意思可以通过重写人为限制数量以达到移除最老元素
    private static final int MAX_ENTRIES = 100;
     
    protected boolean removeEldestEntry(Map.Entry eldest) {
        return size() > MAX_ENTRIES;
    } 

 

注意:LinkedHashMap中使用有head是指向链表的头,tail是指向链表的尾节点。

在LinkedHashMap中主要就是三个方法实现了双链表的前后引用的关联。其中AfterNodeRemoval()是在删除p节点之后,移除p节点用于前后的节点之间关系。使得p.before=null & p.after=null;AfterNodeInsertion()上面有说,意思就是插入的时候看是否需要将节点移除;最后就是AfterNodeAccess()方法。

LinkedHashMap结构中有一个新的newNode,这个与HashMap不同,这个方法被LinkedHashMap重写了。

  Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
        LinkedHashMap.Entry<K,V> p =
            new LinkedHashMap.Entry<K,V>(hash, key, value, e);
     // 链接至尾节点 linkNodeLast(p);
return p; }   // link at the end of list private void linkNodeLast(LinkedHashMap.Entry<K,V> p) { LinkedHashMap.Entry<K,V> last = tail; tail = p; if (last == null) head = p; else { p.before = last; last.after = p; } }
posted @ 2019-12-16 19:52  前进山峦  阅读(291)  评论(0编辑  收藏  举报