lru实现java效率,java实现LRU算法及编码实现LRU策略缓存

概念

LRU(least recently used)就是将最近不被访问的数据给淘汰掉,LRU基于一种假设:认为最近使用过的数据将来被使用的概率也大,最近没有被访问的数据将来被使用的概率比较低。

原理

LRU一般通过链表形式来存放缓存数据,新插入或被访问的数据放在链表头部,超过一定阈值后,自动淘汰链表尾部的数据。下图很形象的说明了LRU缓存淘汰过程。(图片来自网络)

32bd37aaa17d219ab05eda49cb46728a.png

步骤:

1、新插入A, 将A放置在队列头部

2、新插入B, 将B放置在队列头部, A自动推举次席。

3、新插入C, 将C放置在队列头部, B自动推举次席。

4、新插入D, 将D放置在队列头部, C自动推举次席。

5、新插入E, 将E放置在队列头部, D自动推举次席。

6、新插入E, 将E放置在队列头部, 这时队列长度大于阈值,自动将尾部数据A给淘汰掉

7、访问数据C,然后将C重新放置在队列头部。

8、新插入E, 将E放置在队列头部, 这时队列长度大于阈值,自动淘汰尾部数据B

编码实现LRU策略缓存

/**

* 2020/4/11.

*

* 使用链表+hashmap来实现, 这里没有考虑并发情况, 所以在代码中没有使用锁

*/

public class LRUCache {

class CacheNode {

public CacheNode before;

public Object key;

public Object value;

public CacheNode after;

public CacheNode() {

}

}

private HashMap caches;

private int maxCapacity;

private int currentCacheSize;

/**

* 头结点, 头结点不参与淘汰,只是作为标识链表中的第一个节点

*/

private CacheNode head;

/**

* 尾节点, 尾节点不参与淘汰, 只是作为标识链表中最后一个节点

*/

private CacheNode tail;

public LRUCache(int maxCapacity) {

this.maxCapacity = maxCapacity;

caches = new HashMap<>(maxCapacity);

head = tail = new CacheNode();

head.after = tail; //对head 的after节点赋值, 防止后续操作出现空指针异常

tail.before = head; // 对tail的before节点赋值, 防止后续操作出现空指针异常

}

public void put(K k, V v) {

CacheNode node = caches.get(k);

if (node == null) {

if (currentCacheSize >= maxCapacity) {

caches.remove(tail.before.key); //淘汰尾部的元素

removeLast();

}

node = new CacheNode();

node.key = k;

currentCacheSize ++;

}

node.value = v;

moveToFirst(node); // LRU策略, 新插入的元素放置到队列头部

caches.put(k, node);

}

public void moveToFirst(CacheNode node) {

CacheNode n = head.after;

head.after = node;

node.before = head;

n.before = node;

node.after = n;

}

public void removeLast() {

CacheNode n = tail.before.before;

n.after = tail;

tail.before = n;

}

public Object get(K k) {

CacheNode node = caches.get(k);

if (node == null) {

return null;

}

Object v = node.value;

moveToFirst(node);

return v;

}

public Object remove(K k) {

CacheNode node = caches.get(k);

if (node == null) {

return null;

}

CacheNode pre = node.before;

CacheNode next = node.after;

pre.after = next;

next.before = pre;

caches.remove(k);

currentCacheSize --;

return node.value;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值