缓存是基于程序和数据的局部性实现的。
(数据在连续的内存空间内反复读写)因此将经常需要使用的数据保存到缓存中,每当需要的时候就先去找缓存,如果缓存中命中,若未命中就把数据加到缓存,因此必然会出现符合某些场景的不同效率的替换策略使得缓存的效率有效提升。
Java里可以使用LinkedHashMap,底层由双端链表和HashMap实现。
HashMap可以实现查询的时候O(1)时间复杂度,但是无法确定哪条数据的使用顺序
双端链表可以实现增删的时候的O(1)时间复杂度,但是无法实现随机访问
因此结合二者可以实现LRU
一开始确定缓存大小,
链表都是单向操作的,HashMap用来视作缓存,
需要取一个元素(检查缓存中是否存在的时候),
如果有就返回,否则就插入数据到缓存,此时需要分两种情况
1:当缓存容量超出到最大值的时候,需要从链表头部删除首个元素,然后把元素插入到链表尾部。
2:如果缓存容量还足够,就直接插入到链表尾部。
很容易会想到queue也可以实现先进先出的功能,但是使用queue的话,无法将重复用到的数据移动到数据尾部。
显然单向链表也可以实现将首部尾部数据的插入和删除,
但是考虑到单向链表进行删除节点操作时需要多进行一次遍历,需要遍历到删除节点的前驱节点,,然后改变指针,而使用双向链表的情况下,由于双向链表本身有指向前驱节点的指针,因此相比单链表而言少了一次遍历,效率更高
参考资料 https://www.jianshu.com/p/b1ab4a170c3c