【记】LinkedHashMap的理解

2 篇文章 0 订阅

记:
今天面试有两道印象比较深刻的题目。Java语言的。

关于LinkedHashMap类的实现

LinkedHashMap类
@API
LinkedHashMap类
public class LinkedHashMap

    /**
     * The head of the doubly linked list.
     */
    private transient Entry<K,V> header;

下面是关于Entry的创建

    private static class Entry<K,V> extends HashMap.Entry<K,V> {
        // These fields comprise the doubly linked list used for 
        // iteration.
        //类的entry里面增加了双向链表需要用到的墙后两个fields成员变量
        Entry<K,V> before, after;

        Entry(int hash, K key, V value, HashMap.Entry<K,V> next) {
            super(hash, key, value, next);
        }

        /**
         * Removes this entry from the linked list.
         */
        private void remove() {
            before.after = after;
            after.before = before;
        }

        /**
         * Inserts this entry before the specified existing entry 
         * in the list.
         */
        private void addBefore(Entry<K,V> existingEntry) {
            after  = existingEntry;
            before = existingEntry.before;
            before.after = this;
            after.before = this;
        }

        /**
         * 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.
         */
        //这里只重写了HashMap的recordAccess方法来实现链表的维护
        void recordAccess(HashMap<K,V> m) {
            LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
            if (lm.accessOrder) {
                lm.modCount++;
                remove();
                addBefore(lm.header);
            }
        }

        void recordRemoval(HashMap<K,V> m) {
            remove();
        }
    }

在LinkedHashMap的初始化之处,初始化了链表

    /**
     * Called by superclass constructors and pseudoconstructors (clone,
     * readObject) before any entries are inserted into the map.   
     * Initializes the chain.
     */
    @Override
    void init() {
        header = new Entry<>(-1, null, null, null);
        header.before = header.after = header;
    }

经过上面的代码,我们可以看到LinkedHashMap对链表的基本实现过程。

LinkedHashMap特性

就是实现了链表方法
优势在于使用双向链表来会维护Map的key-value对的插入顺序。key-value对就是Entry了。
LinkedHashMap可以避免对HashMap里的key-value对进行排序(只要插入key-value对时保持顺序就可以了),同时又可以避免使用TreeMap所增加的成本。
但是,由于LinkedHashMap需要维护元素的插入顺序,因此性能略低于HashMap的性能;再但是,因为它以链表来维护,所以在迭代访问Map里的全部元素时候有较好的性能。

下面是LinkedHashMap的迭代器实现代码

    private abstract class LinkedHashIterator<T> implements Iterator<T> {
        Entry<K,V> nextEntry    = header.after;
        Entry<K,V> lastReturned = null;

        /**
         * The modCount value that the iterator believes that the 
         * backing List should have.  If this expectation is 
         * violated, the iterator  has detected concurrent 
         * modification.
         */
        int expectedModCount = modCount;

        public boolean hasNext() {
            return nextEntry != header;
        }

        public void remove() {
            if (lastReturned == null)
                throw new IllegalStateException();
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();

            LinkedHashMap.this.remove(lastReturned.key);
            lastReturned = null;
            expectedModCount = modCount;
        }

        Entry<K,V> nextEntry() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            if (nextEntry == header)
                throw new NoSuchElementException();

            Entry<K,V> e = lastReturned = nextEntry;
            nextEntry = e.after;
            return e;
        }
    }

今天LinkedHashMap的了解大概到这里。有机会再深入补充。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值