手撸 LRU

146. LRU 缓存

 

LRU:Least Recently Used (最近最少使用优先)

这是一种最近最少使用优先的淘汰算法,顾名思义优先把最近最少使用的任务淘汰掉 (感觉说了一个废话。。。)

下面直接举一个详细的例子说明:

缓存区大小:3

任务池大小:5

时刻一:启动任务 1,此时任务 1 加入缓存区

  • 缓存区内容:任务 1

时刻二:启动任务 2,此时任务 2 加入缓存区

  • 缓存区内容:任务 2 -> 任务 1

时刻三:调用任务 1

  • 缓存区内容:任务 1 -> 任务 2

时刻四:启动任务 3,此时任务 3 加入缓存区

  • 缓存区内容:任务 3 -> 任务 1 -> 任务 2

时刻五:启动任务 4,此时缓存区已满,任务 4 加入缓存区之前需要淘汰最近最少使用的任务,即任务 2

  • 缓存区内容:任务 4 -> 任务 3 -> 任务 1

时刻六:调用任务 1

  • 缓存区内容:任务 1 -> 任务 4 -> 任务 3

时刻七:启动任务 5,此时缓存区已满,任务 5 加入缓存区之前需要淘汰最近最少使用的任务,即任务 3

  • 缓存区内容:任务 5 -> 任务 1 -> 任务 4

相信上面的流程已经非常情况了,那么如何实现这种效果呢??

而且,「加入新任务、调用任务、淘汰任务」都需要时间复杂度为 O(1)

解决方案:双向链表 ➕ Hash 表

我们规定:双向链表的头节点方向为最近最少使用的节点,而每次新加入节点都插入到尾节点

OK,下面开始构造「双向链表」的数据结构

好了,基础的数据结构构造好了后,我们开始今天的核心部分

 

上面都是纯手动实现的 API,下面给出借助LinkedListHashMap实现的代码