LRU缓存类java_LRU缓存的java实现

importjava.util.Map;importjava.util.WeakHashMap;/*** LRU缓存 (Least Recently Used 删除最近未使用缓存)*/

public class LRUCache{/*** 缓存node结构 (双向链接)

*

*@param 缓存node的key类型

*@param 缓存node的value类型*/

private class Node{/*** 双向链接node的前一个结点*/

private Nodeprev;/*** 双向链接node的后一个结点*/

private Nodenext;/*** 缓存的key*/

privateTKey key;/*** 缓存的value*/

privateTValue value;publicNode() {

}publicNode(TKey key, TValue value) {this.key =key;this.value =value;

}

@OverridepublicString toString() {return "Node{" +

"key=" + key +

", value=" + value +

'}';

}

}/*** 增加Map来存储具体缓存项,来实现O(1)访问*/

private final Map> cache = new WeakHashMap<>();/*** 缓存最大数量*/

private final intcapacity;/*** 当前缓存数量*/

private intsize;/*** 双向链接的header*/

private final Nodeheader;/*** 双向链接的tail*/

private final Nodetail;/*** 获取缓存

*

*@paramkey 缓存key

*@return缓存value*/

public TValue get(finalTKey key) {

Node node =cache.get(key);if (node == null) {return null;

}//移到header

synchronized(cache) {

move2Header(node);

}returnnode.value;

}/*** 添加数据

*

*@paramkey 缓存key

*@paramvalue 缓存value*/

public void put(final TKey key, finalTValue value) {

Node node =cache.get(key);if (node == null) {synchronized(cache) {if (size >=capacity) {//删除尾部

Node expireNode =removeTail();

cache.remove(expireNode.key);this.size--;

}

node=insertHeader(key, value);

cache.put(key, node);this.size++;

}

}else{

node.value=value;synchronized(cache) {

move2Header(node);

}

}

}/*** 移除缓存

*

*@paramkey 缓存key*/

public void remove(finalTKey key) {

Node node =cache.get(key);if (node == null) {return;

}synchronized(cache) {

remove(node);this.cache.remove(key);this.size--;

}

}/*** 添加缓存key/value到链表的header

*

*@paramkey 缓存key

*@paramvalue 缓存value*/

private Node insertHeader(final TKey key, finalTValue value) {

Node node = new Node<>(key, value);returninsertHeader(node);

}/*** 添加缓存node到链表的header

*

*@paramnode 缓存node

*@return缓存node*/

private Node insertHeader(final Nodenode) {

node.prev= this.header;

node.next= this.header.next;this.header.next.prev =node;this.header.next =node;returnnode;

}/*** 移动缓存node到header

*

*@paramnode 缓存node*/

private void move2Header(final Nodenode) {

remove(node);

insertHeader(node);

}/*** 删除链表尾部*/

private NoderemoveTail() {

Node node = this.tail.prev;

remove(node);returnnode;

}/*** 删除链表的node*/

private void remove(final Nodenode) {

node.prev.next=node.next;

node.next.prev=node.prev;

}/*** 添加缓存node到链表的tail

*

*@paramkey 缓存node的key

*@paramvalue 缓存node的value

*@return缓存node*/

private Node putTail(final TKey key, finalTValue value) {

Node node = new Node<>(key, value);returnputTail(node);

}/*** 添加缓存node到链表的tail

*

*@paramnode 缓存node

*@return缓存node*/

private Node putTail(final Nodenode) {

node.prev= this.tail.prev;

node.next= this.tail;this.tail.prev.next =node;this.tail.prev =node;returnnode;

}/*** .ctor

*

*@paramcapacity 最大缓存数量*/

public LRUCache(final intcapacity) {this.capacity =capacity;this.header = new Node<>();this.tail = new Node<>();this.header.next = this.tail;this.header.prev = null;this.tail.prev = this.header;this.tail.next = null;this.size = 0;

}

@OverridepublicString toString() {

Node node = this.header.next;

StringBuilder sb= newStringBuilder();

sb.append("(size:");

sb.append(size);

sb.append(")");while (node != this.tail) {

sb.append(node.key);

sb.append(":");

sb.append(node.value);

sb.append(",");

node=node.next;

}//sb.append(cache.toString());

returnsb.toString();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LRU(Least Recently Used)缓存机制是一种常见的缓存淘汰策略,它会将最近最少使用的缓存数据淘汰出去,从而保持缓存的容量在一定的范围内。 在 Java 中,我们可以使用 LinkedHashMap 实现 LRU 缓存机制。LinkedHashMap 是一种哈希表和链表实现的有序映射表,它允许我们按照元素的插入顺序或访问顺序进行遍历。我们可以通过设置 accessOrder 参数为 true 来启用按访问顺序排序。 下面是一份简单的 Java 实现代码: ```java import java.util.LinkedHashMap; import java.util.Map; public class LRUCache<K, V> extends LinkedHashMap<K, V> { private int capacity; public LRUCache(int capacity) { super(capacity, 0.75f, true); this.capacity = capacity; } protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { return size() > capacity; } } ``` 在上面的代码中,我们继承了 LinkedHashMap ,并在构造函数中调用了父的构造函数,同时设置 accessOrder 为 true。我们还实现了 removeEldestEntry 方法,该方法会在每次插入元素时被调用,如果当前缓存的元素数量超过了设定的容量,就会将最老的元素删除。 使用该 LRU 缓存的示例代码: ```java LRUCache<Integer, Integer> cache = new LRUCache<>(2); cache.put(1, 1); cache.put(2, 2); System.out.println(cache.get(1)); // 输出 1 cache.put(3, 3); System.out.println(cache.get(2)); // 输出 null cache.put(4, 4); System.out.println(cache.get(1)); // 输出 null System.out.println(cache.get(3)); // 输出 3 System.out.println(cache.get(4)); // 输出 4 ``` 在上面的示例代码中,我们创建了一个容量为 2 的 LRU 缓存,并且按顺序插入了三个元素。由于容量只有 2,因此最后插入的元素 4 会将元素 1 淘汰出缓存,而元素 2 虽然是最近使用的,但是由于已经被淘汰出缓存,因此返回的值为 null。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值