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

来源:互联网 发布:四川省住建厅数据共享 编辑:程序博客网 时间:2024/06/03 15:06
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.数据结构特性可以叠加使用。数组特性增加链表特性,可以进行扩容元素属性。

 






原创粉丝点击