这是一个非常简单的LRU Cache类,利用LinkedHashMap实现
package com.kivensoft.util;
import java.util.LinkedHashMap;
import java.util.Collection;
import java.util.Map;
import java.util.ArrayList;
/**An LRU cache, based on LinkedHashMap
.
* 这个缓存修正了元素的最大值计算公式(cacheSize
).
* 如果添加项的时候缓存满了,最老最少用的项将被抛弃
* 这个类是线程安全的,所有函数是线程同步的
* @author: Kiven Lee
* @version: 1.0.0
* 2013-10-11 22:17
*/
public class LRUCache {
private static final float hashTableLoadFactor = 0.75f;
private LinkedHashMap map;
protected int cacheSize;
/**创建新的缓存类.
* @param cacheSize 最大缓存的记录数量
*/
public LRUCache(int cacheSize) {
this.cacheSize = cacheSize;
int hashTableCapacity = (int) Math.ceil(cacheSize / hashTableLoadFactor) + 1;
map = new LinkedHashMap(hashTableCapacity, hashTableLoadFactor, true) {
// 内嵌匿名类
private static final long serialVersionUID = 1;
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > LRUCache.this.cacheSize;
}
};
}
/**根据键获取缓存中的数据.
* @param key 键值
* @return 对应键值的数据, 如果不存在则返回null
*/
public synchronized V get(K key) {
return map.get(key);
}
/**把记录加入缓存中.
* @param key 键值
* @param value 对应的数据
*/
public synchronized void put(K key, V value) {
map.put(key, value);
}
/**清空缓存. */
public synchronized void clear() {
map.clear();
}
/**返回缓存中已经使用的记录数
* @return 已经使用的数量.
*/
public synchronized int usedEntries() {
return map.size();
}
/**以集合的类型返回所有缓存的副本
* @return a Collection
所有缓存内容的副本.
*/
public synchronized Collection<Map.Entry> getAll() {
return new ArrayList<Map.Entry>(map.entrySet());
}
// Test routine for the LRUCache class.
public static void main(String[] args) {
LRUCache c = new LRUCache(3);
c.put("1", "one"); // 1
c.put("2", "two"); // 2 1
c.put("3", "three"); // 3 2 1
c.put("4", "four"); // 4 3 2
if (c.get("2") == null) throw new Error(); // 2 4 3
c.put("5", "five"); // 5 2 4
c.put("4", "second four"); // 4 5 2
// Verify cache content.
if (c.usedEntries() != 3) throw new Error();
if (!c.get("4").equals("second four")) throw new Error();
if (!c.get("5").equals("five")) throw new Error();
if (!c.get("2").equals("two")) throw new Error();
// List cache content.
for (Map.Entry e : c.getAll())
System.out.println(e.getKey() + " : " + e.getValue());
}
} // end class LRUCache