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();
}
}