用map实现LRU算法(LinkedHashMap)

LinkedHashMap是把HashMap和双向链表合二为一,它将所有entry节点放入一个双向链表的hashmap,其内部维持的顺序是元素插入的顺序,而且能实现lru算法。

  下面是get方法的定义:

 public V get(Object key) {

        Entry<K,V> e = (Entry<K,V>)getEntry(key);

        if (e == null)

            return null;

        e.recordAccess(this);

        return e.value;

    }

其中recordAccess定义如下:

  void recordAccess(HashMap<K,V> m) {

            LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;

            if (lm.accessOrder) {

                lm.modCount++;

                remove();

                addBefore(lm.header);

            }

     }

这里的addBefore方法: 

  private void addBefore(Entry<K,V> existingEntry) {

            after  = existingEntry;

            before = existingEntry.before;

            before.after = this;

            after.before = this;

        }

可以看到addBefore方法中,是把当前访问的元素挪到了head的前面,即放到了链表头,如此要实现lru只需要从链表末尾往前删除就可以了。注意在初始化LinkedHashMap的时候,会传入一个accessOrder属性,如果为true,则代表entry是按照访问顺序排序的,如果为false,则代表是按照插入顺序排序的,即在put的时候,entry会放在双向链表的尾部。put方法也会调用addBefore()

 

 put顺序:

LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
map.put("星期一", 40);
map.put("星期二", 43);
map.put("星期三", 35);
map.put("星期四", 55);
map.put("星期五", 45);
map.put("星期六", 35);
map.put("星期日", 30);
for (Map.Entry<String, Integer> entry : map.entrySet()){
     System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
}

结果:

key: 星期一, value: 40
key: 星期二, value: 43
key: 星期三, value: 35
key: 星期四, value: 55
key: 星期五, value: 45
key: 星期六, value: 35
key: 星期日, value: 30

 

posted @   MarkLeeBYR  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示