更多 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());
}
}