LinkedHashMap原理分析
来源:互联网 发布:全国心智障碍者数据 编辑:程序博客网 时间:2024/04/27 20:49
LinkedHashMap原理分析
一.实现
LinkedHashMap继承HashMap数据结构:HashMapEntry(key,value)--》LinkedHashMapEntry(key,value+before指针和after指针(双向链表))1.构造函数LinkedHashMap/* accessOrder true if the ordering should be done based on the last access (from least-recently accessed to most-recently accessed), and false if the ordering should be the order in which the entries were inserted.*/public LinkedHashMap( int initialCapacity, float loadFactor, boolean accessOrder) { super(initialCapacity, loadFactor); init(); this.accessOrder = accessOrder;}super(initialCapacity, loadFactor) { // 新建一个HashMap-->创建HashMap对应的集合 ...}@Override void init() { header = new LinkedEntry<K, V>();}/* LinkedEntry是双向链表+HashMap的item LinkedEntry是HashMapEntry的子类 HashMapEntry是HashMap的item*/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);// 调用HashMap的构造函数 this.nxt = nxt; this.prv = prv; }}2.put函数--同HashMap的put函数// 覆写该函数// 修改已经put进去的key对应的value的时候会调用该函数@Override void preModify(HashMapEntry<K, V> e) { if (accessOrder) { makeTail((LinkedEntry<K, V>) e); }}// 将e元素插入到循环双向链表的末尾(如果之前已经插入到循环双向链表中,则删除,然后插入到末尾)/*** 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) {// Tail:尾巴 // Unlink e e.prv.nxt = e.nxt; e.nxt.prv = e.prv; // header是LinkedEntry的链表,LinkedEntry在1构造函数中有介绍 // Relink e as tail LinkedEntry<K, V> header = this.header; // 将e插入到循环双向链表的最后一个元素 LinkedEntry<K, V> oldTail = header.prv; e.nxt = header; e.prv = oldTail; oldTail.nxt = header.prv = e; modCount++;}// 覆写该函数--相当于调用makeTail,把item插入到双向队列的末尾@Override void addNewEntry(K key, V value, int hash, int index) { LinkedEntry<K, V> header = this.header; // Remove eldest entry if instructed to do so. LinkedEntry<K, V> eldest = header.nxt; if (eldest != header && removeEldestEntry(eldest)) { remove(eldest.key); } // Create new entry, link it on to list, and put it into table LinkedEntry<K, V> oldTail = header.prv; LinkedEntry<K, V> newTail = new LinkedEntry<K,V>(key, value, hash, table[index], header, oldTail); table[index] = oldTail.nxt = header.prv = newTail;}3.get函数// 该实现和HashMap的get函数实现几乎一样,除了注释的那句代码外@Override public V get(Object key) { ... // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590). int hash = secondaryHash(key); HashMapEntry<K, V>[] tab = table; // HashMap.java的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))) { if (accessOrder) // 添加的代码.如果是按照Lru算法实现,这重新调整该item在循环双向链表中的位置 makeTail((LinkedEntry<K, V>) e); return e.value; } } return null;}4.remove函数--同HashMap的remove函数// 覆写通知函数// 将该item从双向循环链表中删除@Override void postRemove(HashMapEntry<K, V> e) { LinkedEntry<K, V> le = (LinkedEntry<K, V>) e; le.prv.nxt = le.nxt; le.nxt.prv = le.prv; le.nxt = le.prv = null; // Help the GC (for performance)}
二.总结
1.要了解LinedHashMap的实现,要先知道他的父类HashMap的实现,LinkedHashMap的大部分实现都在他父类中实现2.当开启Lru算法的时候(accessOrder参数设置为true),LinkedHashMap比HashMap多的是该类自己维护双向循环链表,当增删改的时候会修改该链表,把最新的item放到末尾(Tail)3.本质:LinkedHashMap == HashMap + LinkedList
阅读全文
0 0
- LinkedHashMap实现原理分析
- LinkedHashMap原理分析
- LinkedHashMap原理分析
- Hashmap\LinkedHashMap的实现原理分析
- LinkedHashMap 原理
- LinkedHashMap分析
- LinkedHashmap分析
- LinkedHashMap分析
- LinkedHashMap的实现原理
- LinkedHashMap的实现原理
- LinkedHashMap的实现原理
- LinkedHashMap的实现原理
- LinkedHashMap的实现原理
- java linkedhashmap 原理
- LinkedHashMap实现原理-学习
- LinkedHashMap实现原理
- LinkedHashMap 的实现原理
- LinkedHashMap 的实现原理
- KVM安装报错Failed to connect socket to '/var/run/libvirt/libvirt-sock': No such file or directory
- canvas图片体积压缩
- Python3 异常处理
- HDU6045+Is Derek lying?(思路)+多校联赛第二场
- Find The Multiple(poj 1426)
- LinkedHashMap原理分析
- 104/111 Maximum/Minimum Depth of Binary Tree(二叉树求深度)
- 玩玩JFinal第一发
- 批处理入门手册之批处理常用DOS命令篇(echo、rem、cd、dir)
- Python中graphics不存在,解决办法
- 图片展示
- 图的存储结构之邻接表
- 【算法】【题解】【usaco】 最受欢迎的牛
- java并发——如何创建线程