用java实现缓存算法LFU,固定缓存只有10的长度,并测试淘汰数据使用
时间: 2024-03-14 16:43:30 浏览: 98
好的,以下是Java实现LFU缓存算法的代码:
```java
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
public class LFUCache<K, V> {
private final int capacity;
private Map<K, V> cache;
private Map<K, Integer> keyCounts;
private Map<Integer, LinkedHashSet<K>> countKeys;
private int minCount;
public LFUCache(int capacity) {
this.capacity = capacity;
cache = new HashMap<>();
keyCounts = new HashMap<>();
countKeys = new HashMap<>();
countKeys.put(1, new LinkedHashSet<>());
minCount = -1;
}
public boolean contains(K key) {
return cache.containsKey(key);
}
public V get(K key) {
if (!cache.containsKey(key)) {
return null;
}
int count = keyCounts.get(key);
keyCounts.put(key, count + 1);
countKeys.get(count).remove(key);
if (count == minCount && countKeys.get(count).isEmpty()) {
minCount++;
}
if (!countKeys.containsKey(count + 1)) {
countKeys.put(count + 1, new LinkedHashSet<>());
}
countKeys.get(count + 1).add(key);
return cache.get(key);
}
public void put(K key, V value) {
if (capacity <= 0) {
return;
}
if (cache.containsKey(key)) {
cache.put(key, value);
get(key);
return;
}
if (cache.size() >= capacity) {
evict();
}
cache.put(key, value);
keyCounts.put(key, 1);
countKeys.get(1).add(key);
minCount = 1;
}
private void evict() {
K evictKey = countKeys.get(minCount).iterator().next();
countKeys.get(minCount).remove(evictKey);
cache.remove(evictKey);
keyCounts.remove(evictKey);
}
}
```
这个实现使用了3个Map,其中keyCounts记录了每个key的访问次数,countKeys记录了每个访问次数对应的key集合,cache是缓存本身。
使用LinkedHashSet是为了保证访问顺序和插入顺序一致,方便找到最近最少使用的key。
以下是一个简单的测试代码:
```java
public static void main(String[] args) {
LFUCache<Integer, String> cache = new LFUCache<>(10);
for (int i = 0; i < 20; i++) {
cache.put(i, "Value " + i);
}
System.out.println(cache.get(0)); // null
System.out.println(cache.get(10)); // "Value 10"
System.out.println(cache.get(19)); // "Value 19"
}
```
这个测试代码插入了20个key,但是缓存只有10的长度,因此前面的10个key已经被淘汰了。`cache.get(0)`返回null,因为0已经被淘汰了,`cache.get(10)`和`cache.get(19)`返回正确的值,因为它们最近被访问过。
阅读全文