LinkedHashMap

基于jdk1.8。

之前分析过LruCache得源码实现,发现主要得功能是通过LinkedHashMap来实现得,所以就看下LinkedHashMap得源码是如何实现得。

              LinkedHashMap_第1张图片

           (图片来源 https://upload-images.jianshu.io/upload_images/4843132-7abca1abd714341d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/739/format/webp)

 

public class LinkedHashMap
    extends HashMap
    implements Map

可以看到是继承HashMap得,看下构造函数。

    /**
     * Constructs an empty insertion-ordered LinkedHashMap instance
     * with the default initial capacity (16) and load factor (0.75).
     */
    public LinkedHashMap() {
        super();
        accessOrder = false;
    }

accessOrder =true 表示插入排序,反之为false则是FIFO。

LinkedHashMap源码中有几个重要得函数,分别是。

    void afterNodeAccess(Node e) { // move node to last
        LinkedHashMap.Entry last;
        if (accessOrder && (last = tail) != e) {
            LinkedHashMap.Entry p =
                (LinkedHashMap.Entry)e, b = p.before, a = p.after;
            p.after = null;
            if (b == null)
                head = a;
            else
                b.after = a;
            if (a != null)
                a.before = b;
            else
                last = b;
            if (last == null)
                head = p;
            else {
                p.before = last;
                last.after = p;
            }
            tail = p;
            ++modCount;
        }
    }

实现得功能是将数据移动到尾部,在LruCache中,尾部得数据表示最近被访问过得,head指向得数据则表示最近没有被访问得。

 

    void afterNodeRemoval(Node e) { // unlink
        LinkedHashMap.Entry p =
            (LinkedHashMap.Entry)e, b = p.before, a = p.after;
        p.before = p.after = null;
        if (b == null)
            head = a;
        else
            b.after = a;
        if (a == null)
            tail = b;
        else
            a.before = b;
    }

看到得是删除下一个节点得数据。

    void afterNodeInsertion(boolean evict) { // possibly remove eldest
        LinkedHashMap.Entry first;
        if (evict && (first = head) != null && removeEldestEntry(first)) {
            K key = first.key;
            removeNode(hash(key), key, null, false, true);
        }
    }

 

可以看到得是插入上一个节点得数据。

 

    // link at the end of list
    private void linkNodeLast(LinkedHashMap.Entry p) {
        LinkedHashMap.Entry last = tail;
        tail = p;
        if (last == null)
            head = p;
        else {
            p.before = last;
            last.after = p;
        }
    }

把节点插入到链表得队尾。

   // apply src's links to dst
    private void transferLinks(LinkedHashMap.Entry src,
                               LinkedHashMap.Entry dst) {
        LinkedHashMap.Entry b = dst.before = src.before;
        LinkedHashMap.Entry a = dst.after = src.after;
        if (b == null)
            head = dst;
        else
            b.after = dst;
        if (a == null)
            tail = dst;
        else
            a.before = dst;
    }

交换两个节点得位置。

总结

LinkedHashMap是通过维护一条双向链表来解决HashMap不能随时保持遍历顺序和插入一致得问题。

你可能感兴趣的:(Java)