更多 Java 集合類方面的文章,請參見文集《Java 集合類》
LRU - Least Recent Used
最近最少使用原則。
可以通過使用 LinkedHashMap 來實現,原因:
- LinkedHashMap 遍歷時按照插入的順序或者訪問的順序。
- 此處我們使用按照 訪問的順序 來遍歷,即最近訪問的元素會出現在遍歷的最前面:
// 將第三個參數 accessOrder 設置為 true
new LinkedHashMap<K, V>(hashTableCapacity, hashTableLoadFactor, true);
- LinkedHashMap 本身有一個方法用于判斷是否需要移除最不常讀取的數,默認不需要移除:
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
return false;
}
- 此處我們需要根據 cache 的容量來重寫該方法,將最近不常使用的元素移除,例如
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > LRUCache.this.cacheSize;
}
完整例子:
public class LRUCache<K, V> {
private static final float hashTableLoadFactor = 0.75f;
private LinkedHashMap<K, V> map;
private int cacheSize;
/**
* Creates a new LRU cache. 在該方法中,new LinkedHashMap<K,V>(hashTableCapacity,
* hashTableLoadFactor, true)中,true代表使用訪問順序
*/
public LRUCache(int cacheSize) {
this.cacheSize = cacheSize;
int hashTableCapacity = (int) Math
.ceil(cacheSize / hashTableLoadFactor) + 1;
map = new LinkedHashMap<K, V>(hashTableCapacity, hashTableLoadFactor,
true) {
// (an anonymous inner class)
private static final long serialVersionUID = 1;
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > LRUCache.this.cacheSize;
}
};
}
public synchronized V get(K key) {
return map.get(key);
}
public synchronized void put(K key, V value) {
map.put(key, value);
}
public synchronized Collection<Map.Entry<K, V>> getAll() {
return new ArrayList<Map.Entry<K, V>>(map.entrySet());
}
}