LinkedHashMap

本文环境为JDK8

LinkedHashMap的目的是有序的map,遍历顺序与塞入顺序相同

我们跟着源代码来看看LinkedHashMap的内部结构

首先是构造器,是HashMap的一个子类,基本数据结构、方法与HashMap相同

public class LinkedHashMap
    extends HashMap
    implements Map

在HashMap的基础上,增加了两个LinkedHashMap.Entry的变量,用来记录一个LinkedList的头和尾,而这个LinkedList就是用来有序的记录各个LinkedHashMap.Entry的

/**
     * The head (eldest) of the doubly linked list.
     */
    transient LinkedHashMap.Entry head;

    /**
     * The tail (youngest) of the doubly linked list.
     */
    transient LinkedHashMap.Entry tail;

我们来看一下put方法,put方法使用的依旧是HashMap的put方法,在put中调用了afterNodeAccess(e),这个方法HashMap本身是空函数,而LinkedHashMap有实现

afterNodeAccess将插入的节点移动到LinkedList的尾部;put的时候有可能是新增,有可能是修改值,无论新增还是修改,都会移动到尾部

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;
        }
    }

然后我们来看看遍历的时候用的entrySet方法,从head节点开始一个个遍历:

public Set> entrySet() {
        Set> es;
        return (es = entrySet) == null ? (entrySet = new LinkedEntrySet()) : es;
    }
final class LinkedEntrySet extends AbstractSet> {
        public final int size()                 { return size; }
        public final void clear()               { LinkedHashMap.this.clear(); }
        public final Iterator> iterator() {
            return new LinkedEntryIterator();
        }
        public final boolean contains(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry e = (Map.Entry) o;
            Object key = e.getKey();
            Node candidate = getNode(hash(key), key);
            return candidate != null && candidate.equals(e);
        }
        public final boolean remove(Object o) {
            if (o instanceof Map.Entry) {
                Map.Entry e = (Map.Entry) o;
                Object key = e.getKey();
                Object value = e.getValue();
                return removeNode(hash(key), key, value, true, true) != null;
            }
            return false;
        }
        public final Spliterator> spliterator() {
            return Spliterators.spliterator(this, Spliterator.SIZED |
                                            Spliterator.ORDERED |
                                            Spliterator.DISTINCT);
        }
        public final void forEach(Consumer> action) {
            if (action == null)
                throw new NullPointerException();
            int mc = modCount;
            for (LinkedHashMap.Entry e = head; e != null; e = e.after)
                action.accept(e);
            if (modCount != mc)
                throw new ConcurrentModificationException();
        }
    }

你可能感兴趣的:(LinkedHashMap)