1. JDBC中的LRUCache:
package com.mysql.cj.util;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = 1L;
protected int maxElements;
public LRUCache(int maxSize) {
super(maxSize, 0.75F, true);
this.maxElements = maxSize;
}
protected boolean removeEldestEntry(Entry<K, V> eldest) {
return this.size() > this.maxElements;
}
}
可以看到其實現的LRUCache其實是繼承自JDK中LinkedHashMap類的,並重寫了removeEldestEntry方法,該方法返回一個布爾值,即當前集合大小大於規定的大小時返回true,否則返回false。
2.LinkedHashMap中的removeEldestEntry()方法
以下是LinkedHashMap中removeEldestEntry的方法,默認返回是false。
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
return false;
}
接着點擊removeEldestEntry方法查找誰調用了它,結果跳到了如下代碼:
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);
}
}
顧名思義,在添加進新元素後,會執行該方法判斷執行要不要踢出最久未被使用的元素。其中evict踢出狀態,時putVal傳給該函數的,除了讀取元素時爲false,其它情況都爲true;當且僅當踢出狀態爲真、鏈表不爲空時以及需要移除最久未使用的元素時,纔會移除元素。
3. LinkedHashMap是如何讀取元素的
需要知道的一點是,LinkedHashMap在讀取元素時,會將元素移動到鏈表尾部,這樣就模擬了類似用棧實現LRU的方法,也解釋了爲什麼讀取元素是也會調用putVal方法的原因