LinkedHashMap分析

LinkedHashMap分析(基于jdk1.8)

HashMap有一个问题就是迭代的顺序无法保证,也就是和put进去的顺序不同,有时候可能需要保证迭代的时候与put进去的顺序一致,这个时候就可以使用LinkedHashMap了

首先要搞清楚为什么HashMap无法保证迭代的顺序和put的顺序为什么无法相同,
首先放入map的桶,也就是数组的顺序是和put的顺序没有联系的,恰恰迭代的时候是根据数组里的顺序来的,代码如下:

final Node nextNode() {
            Node[] t;
            Node e = next;
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            if (e == null)
                throw new NoSuchElementException();
                //把hashmap的table引用给t数组
            if ((next = (current = e).next) == null && (t = table) != null) {
                //do while循环,直到数组中的某个对象不为null时返回null
                do {} while (index < t.length && (next = t[index++]) == null);
            }
            return e;
        }

所以为了解决这个问题,LinkedHashMap的静态内部类Entry继承了HashMap的Node并且增加了before和after的成员变量

static class Entry extends HashMap.Node {
        Entry before, after;
        Entry(int hash, K key, V value, Node next) {
            super(hash, key, value, next);
        }
    }

然后问题来了,增加的这些节点是怎么在put的时候弄上去的呢,看看重写的方法吧
我本来以为是重写了putVal()方法呢,然而我还是naive,其实是重写了newNode()方法

    Node newNode(int hash, K key, V value, Node e) {
        LinkedHashMap.Entry p =
            new LinkedHashMap.Entry(hash, key, value, e);
        //这个方法将put的方法形成一个链表
        linkNodeLast(p);
        return p;
    }
    
    /**
    *私有方法
    *
    **/    
    private void linkNodeLast(LinkedHashMap.Entry p) {
        LinkedHashMap.Entry last = tail;
        tail = p;
        if (last == null)
            head = p;
        else {
            p.before = last;
            last.after = p;
        }

好,再来看看LinkedHashMap的迭代方法,直接看nextNode就行啦:


 final LinkedHashMap.Entry nextNode() {
            LinkedHashMap.Entry e = next;
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            if (e == null)
                throw new NoSuchElementException();
                //终于不用通过桶去循环找下一个不为null的数组对象啦
            current = e;
            next = e.after;
            return e;
        }

你可能感兴趣的:(LinkedHashMap分析)