一、概述
LRU
,全称 Least Recently Used. 最近最少使用算法(最久未使用),一般来说是维护一个缓存(可以用map
,甚至链表都行。重点是思想)。
可以直接维护一个map
, js中的map
是有序的,每次set()
调用的时候都会把新的set 加入到末尾。如图:
LRU
算法的思想是:
- 维护一种空间有限的数据结构。
- 每次存取某个数据以后,将这个数据放到该数据结构的头部。(因为往往现在使用的数据,接下来继续使用的概率会很大)
- 如果空间被用完,淘汰最久没有使用的数据。
二、实现
编写一个类LRU
,实现两个主要的方法:get、set
。构造函数(constructor
)初始化的时候接受一个参数capacity
,用于限制当前实例的容量。
- constructor(capacity):实例化一个对象,限制容量。
- get(key): 获取指定的数据。
- set(key,value):读取指定的数据。
class LRU {
#cache; // 私有变量(缓存,一个map 结构)
#capacity;// 私有变量(缓存的容量)
constructor(capacity) { // 构造函数
this.#capacity = capacity;
this.#cache = new Map();
}
//判断缓存中是否存在某个值
has(key) {
return this.#cache.has(key);
}
// 核心函数(读)
get(key) {
if (!this.has(key)) return null;
// 更新#cache
const value = this.#cache.get(key);
this.#cache.delete(key);
this.#cache.set(key, value);
return value;
}
// 核心函数(存或者更改)
set(key, value) {
// 存在就删掉
if (this.has(key)) this.#cache.delete(key);
// 不管有没有超过,都要往末尾加一个
this.#cache.set(key, value);
// 已经满容量了, 淘汰第一个
if (this.#cache.size > this.#capacity) {
this.#cache.delete(this.#cache.keys().next().value);// 这里使用了迭代器。
}
}
getEntire() {
return this.#cache.entries();
}
}
// 测试
const lru = new LRU(5);
for (let i = 0; i < 10; i ) {
lru.set(i, i);
}
lru.get(7);
lru.get(5);
console.log(lru.getEntire());
看一下输出:
符合预期,完美!!!