jdk源码有感-LinkedHashMap

·  阅读 73

LinkedHashMap

LinkedHashMap是HashMap的一个子类,HashMap是无序的,LinkedHashMap遍历是有序的,下面来看看LinkedHashMap做了什么操作让遍历有序呢?

//LinkedHashMap.put()其实会调用HashMap put()
if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
复制代码

newNode()会调用子类LinkedHashMap的newNode()方法

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;
        }
    }    
复制代码

保证遍历有序的内幕就在linkNodeLast()方法,这里维护了一个双向链表,将插入的结点,依次保存在这

final boolean accessOrder;

if (accessOrder)
            afterNodeAccess(e);

void afterNodeAccess(Node<K,V> e) { // move node to last
        LinkedHashMap.Entry<K,V> last;
        if (accessOrder && (last = tail) != e) {
            LinkedHashMap.Entry<K,V> p =
                (LinkedHashMap.Entry<K,V>)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;
        }
    }
复制代码

将accessOrder设为true时,LinkedHashMap的get()操作,或put()的覆盖操作会原结点的位置移动到双向链表尾部

分类:
阅读
标签:
分类:
阅读
标签: