前面也说到了LinkedHashMap源码解析,感兴趣的可以去看下
今天我们用它来完成LRU(最近最少使用算法)
代码实现:
/**
* 利用LinkedHashMap实现LRU
*/
public class LRULinkedMap<K, V> extends LinkedHashMap<K, V>{
/**
* 缓存数据的个数
*/
private int cacheSize ;
/**
* @Fields serialVersionUID :
*/
private static final long serialVersionUID = 5094536960196819627L;
public LRULinkedMap(int cacheSize) {
super((int)(cacheSize/0.75 + 1),0.75f, true);
this.cacheSize = cacheSize ;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
return cacheSize < size();
}
}
调用的父类构造
用(int)(cacheSize/0.75 + 1)这个计算初始化的容量,避免map中不必要的扩容操作
加载因子用0.75就好了
最重要的是是要设置以访问的顺序
removeEldestEntry方法
在LinkedHashMap的源码解析中有说过,在LinkedHashMap中默认是返回的是false是不会删除数据的,我们在这里如果要控制缓存的数量,当map中的键值对超过设置好的缓存的数量cacheSize时,会删除掉最近最少使用的数据
我们来测试一下
LRULinkedMap<String, String> map = new LRULinkedMap<>(3);
map.put("1", "1");
map.put("2", "2");
map.put("3", "3");
System.out.println(map.toString());//{1=1, 2=2, 3=3}
map.put("4", "4");
System.out.println(map.toString());//{2=2, 3=3, 4=4}
map.get("2");
System.out.println(map.toString());//{3=3, 4=4, 2=2}
我们设置了缓存的数据的数量为3️⃣,当添加第4️⃣个数据,最早一个被添加的数据被删除了,当我们访问lekey为2的数据,它被放置了在链表的末尾,最近最少使用的3被放置在了链表的头部