基础数据结构之LinkedHashMap源码分析

1.LinkedHashMap数据结构是双向循环链表

 LinkedHashMap节点中得知相关内容,Node节点中存在before,after,双向链表特性

 源码如下

/**
* LinkedHashMap entry.
*/
private static class Entry<K,V> extends HashMap.Entry<K,V> {
   //These fields comprise the doubly linked list used for iteration.
   Entry<K,V> before, after;
   Entry(int hash, K key, V value, HashMap.Entry<K,V> next) {
   super(hash, key, value, next);
}



e = header; e != header ;e = e.after 循环链表特性

源码如下:

public boolean containsValue(Object value) {
        // Overridden to take advantage of faster iterator
        if (value==null) {
            for (Entry e = header.after; e != header; e = e.after)//是否包含value,遍历整个链表查看元素是否存在
                if (e.value==null)
                    return true;
        } else {
            for (Entry e = header.after; e != header; e = e.after)
                if (value.equals(e.value))
                    return true;
        }
        return false;
    }


 LinkedHashMap初始化源码如下:

  

 /**
     * Called by superclass constructors and pseudoconstructors (clone,
     * readObject) before any entries are inserted into the map.  Initializes
     * the chain.
     */
    void init() {
        header = new Entry<K,V>(-1, null, null, null);
        header.before = header.after = header; //一个节点前驱指针和后继指针都指向自己
    }



2.LinkedHashMap添加新元素

 

 /**
     * This override alters behavior of superclass put method. It causes newly
     * allocated entry to get inserted at the end of the linked list and
     * removes the eldest entry if appropriate.
     */
    void addEntry(int hash, K key, V value, int bucketIndex) {
        createEntry(hash, key, value, bucketIndex);	//数组中索引放入元素 && 新元素插入到双向循环链表中
        // Remove eldest entry if instructed, else grow capacity if appropriate
        Entry<K,V> eldest = header.after;
        if (removeEldestEntry(eldest)) { 	        //元素相同,移除old Entry元素
            removeEntryForKey(eldest.key);
        } else { 
            if (size >= threshold)                     //如果有效元素size > 扩容因子*size 
                resize(2 * table.length);              //按照两倍大小容量扩容
        }
    }

    /**
     * This override differs from addEntry in that it doesn't resize the
     * table or remove the eldest entry.
     */
    void createEntry(int hash, K key, V value, int bucketIndex) {
        HashMap.Entry<K,V> old = table[bucketIndex];
	Entry<K,V> e = new Entry<K,V>(hash, key, value, old);//创建一个新的Entry节点
        table[bucketIndex] = e;                             //新的Entry节点,放入到table数组中,table数组是HashMap类的属性
        e.addBefore(header);                                //新的Entry节点,插入到双向循环链表中
        size++;                                             //有效元素大小+1
    }


3.LinkedHashMap获取访问元素特性

   public V get(Object key) {
        Entry<K,V> e = (Entry<K,V>)getEntry(key); 	//调用父类HashMap方法获取元素
        if (e == null)
            return null;
        e.recordAccess(this);       			//访问后,对该访问痕迹进行记录,然后重新排序。从而实现LRU淘汰最久未使用的元素
        return e.value;
    }

      /**
         * This method is invoked by the superclass whenever the value
         * of a pre-existing entry is read by Map.get or modified by Map.set.
         * If the enclosing Map is access-ordered, it moves the entry
         * to the end of the list; otherwise, it does nothing.
         */
        void recordAccess(HashMap<K,V> m) {
            LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
            if (lm.accessOrder) {     			//如果打开了accessOrder开关
                lm.modCount++;     			//访问记录modCount自增1
                remove(); 
                addBefore(lm.header);     		//访问的元素,前面移动
            }
        }


     优化后的代码

   public V get(Object key) {
        Entry<K,V> e = (Entry<K,V>)getEntry(key);
        if (e == null)
            return null;
       if(e.accessOrder) 			//如果打开了accessOrder开关,进行排序。可以省略强制转化的效率
        e.recordAccess(this);
        return e.value;
    }



总结:

   1.数据结构特性可以叠加使用。数组特性增加链表特性,可以进行扩容元素属性。

 






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值