LinkedHashMap源码探究

LinkedHashMap继承于HashMap,有HashMap的所有特性,除此之外LinkedHashMap维护了一个双重链表,这个链表定义了元素的访问顺序包括:插入顺序和访问顺序,默认为按照插入顺序

关于HashMap介绍参考以下
http://blog.csdn.net/nuannuandetaiyang/article/details/71108241

LinkedHashMap的构造函数
    public LinkedHashMap() {
        init();
        accessOrder = false;//元素顺序,默认为插入顺序
    }
    public LinkedHashMap(int initialCapacity) {
        //调用HashMap的构造方法
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }
    public LinkedHashMap(int initialCapacity, float loadFactor) {
        this(initialCapacity, loadFactor, false);
    }
    public LinkedHashMap(
            int initialCapacity, float loadFactor, boolean accessOrder) {
        super(initialCapacity, loadFactor);
        init();
        this.accessOrder = accessOrder;
    }

LinkedHashMap数组的每一项也针对HashMapEntry做了延伸,添加了一个指向后一个元素的nxt指针和前一个元素的prv指针

    static class LinkedEntry<K, V> extends HashMapEntry<K, V> {
        LinkedEntry<K, V> nxt;
        LinkedEntry<K, V> prv;

        /** Create the header entry */
        LinkedEntry() {
            super(null, null, 0, null);
            nxt = prv = this;
        }

        /** Create a normal entry */
        LinkedEntry(K key, V value, int hash, HashMapEntry<K, V> next,
                    LinkedEntry<K, V> nxt, LinkedEntry<K, V> prv) {
            super(key, value, hash, next);
            this.nxt = nxt;
            this.prv = prv;
        }
    }
LinkedHashMap的数据读取
    @Override public V get(Object key) {
        /*
         * This method is overridden to eliminate the need for a polymorphic
         * invocation in superclass at the expense of code duplication.
         */
        if (key == null) {
            HashMapEntry<K, V> e = entryForNullKey;
            if (e == null)
                return null;
            if (accessOrder)
                makeTail((LinkedEntry<K, V>) e);
            return e.value;
        }

        int hash = Collections.secondaryHash(key);
        HashMapEntry<K, V>[] tab = table;
        for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
                e != null; e = e.next) {
            K eKey = e.key;
            if (eKey == key || (e.hash == hash && key.equals(eKey))) {
            // 如果定义了LinkedHashMap的迭代顺序为访问顺序,则删除以前位置上的元素,并将最新访问的元素添加到链表表头。
                if (accessOrder)
                    makeTail((LinkedEntry<K, V>) e);
                return e.value;
            }
        }
        return null;
    }

    /**
     * Relinks the given entry to the tail of the list. Under access ordering,
     * this method is invoked whenever the value of a  pre-existing entry is
     * read by Map.get or modified by Map.put.
     */
    private void makeTail(LinkedEntry<K, V> e) {
        // Unlink e
        //从链表中删除当前元素
        e.prv.nxt = e.nxt;
        e.nxt.prv = e.prv;
        //添加元素到链表头
        // Relink e as tail
        //得到头指针
        LinkedEntry<K, V> header = this.header;
        //临时保存header指向的prv元素
        LinkedEntry<K, V> oldTail = header.prv;
        e.nxt = header;
        e.prv = oldTail;
        oldTail.nxt = header.prv = e;
        modCount++;
    }

image
新增的节点插入过程见图示

整体跟HashMap的数据读取没多大区别,主要的区别在于会根据accessOrder的状态执行makeTail方法,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值