問:簡單說說什么是 LRU板丽?
答:LRU 是一種流行的替換算法,它的全稱是 Least Recently Used,最近最少使用兑凿,常常在緩存設(shè)計的場景中充當(dāng)一種策略,它的核心思路是最近剛被使用的很快再次被用的可能性最高茵瘾,而最久沒被訪問的很快再次被用的可能性最低礼华,所以被優(yōu)先清理。
問:請使用 Java 集合實現(xiàn)一個簡約優(yōu)雅的 LRU 容器拗秘?
答:由于 LinkedHashMap 天生支持插入順序或者訪問順序的 key-value 對圣絮,而 LRU 算法的核心恰巧用到它的訪問順序特性,即對一個鍵執(zhí)行 get雕旨、put 操作后其對應(yīng)的鍵值對會移到鏈表末尾扮匠,所以最末尾的是最近訪問的,最開始的是最久沒被訪問的凡涩。
LinkedHashMap 有一個 boolean 類型的 accessOrder 參數(shù)棒搜,當(dāng)該參數(shù)為 true 時則按照元素最后訪問時間在雙向鏈表中排序,為 false 則按照插入順序排序活箕,默認為 false力麸,所以這里需要的操作就是 accessOrder 為 true 的情況。
所以基于 LinkedHashMap 的特性實現(xiàn)的 LRU 容器如下:
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
private int maxEntries;//maxEntries 最大緩存?zhèn)€數(shù)
public LRUCache(int maxEntries) {
super(16, 0.75f, true);
this.maxEntries = maxEntries;
}
//在添加元素到LinkedHashMap后會調(diào)用這個方法育韩,傳遞的參數(shù)是最久沒被訪問的鍵值對克蚂,
// 如果這個方法返回true則這個最久的鍵值對就會被刪除,LinkedHashMap的實現(xiàn)總是返回false筋讨,
// 所以容量沒有限制埃叭。
@Override
protected boolean removeEldestEntry(Entry<K, V> eldest) {
return size() > maxEntries;
}
}
可以看見實現(xiàn)的簡約 LRU 容器核心優(yōu)雅點就是充分利用了 LinkedHashMap 的有序性特性和容量限制特性。