LRU算法的精简实现(基于Java)

LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
public class Main {
    static class LRULinkedHashMap<K,V> extends LinkedHashMap<K,V> {
        //定义缓存的容量
        private int capacity;
        //带参数的构造器
        LRULinkedHashMap(int capacity){
            //如果accessOrder为true的话,则会把访问过的元素放在链表后面,放置顺序是访问的顺序
            //如果accessOrder为flase的话,则按插入顺序来遍历
            super(16,0.75f,true);
            //传入指定的缓存最大容量
            this.capacity=capacity;
        }
        //实现LRU的关键方法,如果map里面的元素个数大于了缓存最大容量,则删除链表的顶端元素
        @Override
        public boolean removeEldestEntry(Map.Entry<K, V> eldest){
            return size()>capacity;
        }
    }
    //test
    public static void main(String[] args) {
        LRULinkedHashMap<String, Integer> testCache = new LRULinkedHashMap<>(3);
        testCache.put("A", 1);
        testCache.put("B", 2);
        testCache.put("C", 3);
        System.out.println(testCache.get("B"));
        System.out.println(testCache.get("A"));
        testCache.put("D", 4);
        System.out.println(testCache.get("D"));
        System.out.println(testCache.get("C"));
    }
}

API的使用:

  1. 首先是LinkedHashMap的构造器:
//如果accessOrder为true的话,则会把访问过的元素放在链表后面,放置顺序是访问的顺序
public LinkedHashMap(int initialCapacity,
                     float loadFactor,
                     boolean accessOrder) {
    super(initialCapacity, loadFactor);
    this.accessOrder = accessOrder;
}
  1. 重写removeEldestEntry方法
//removeEldestEntry方法会在afterNodeInsertion中调用
//在每次put操作末尾会调用afterNodeInsertion方法。可以利用此方法删除链表的顶端元素。
void afterNodeInsertion(boolean evict) { // possibly remove eldest
    LinkedHashMap.Entry<K,V> first;
    if (evict && (first = head) != null && removeEldestEntry(first)) {
        K key = first.key;
        removeNode(hash(key), key, null, false, true);
    }
}
原文地址:https://www.cnblogs.com/keeya/p/9602691.html