创建链表ListNode<K,V>类
/**
* @author :linwl
* @date :Created in 2019/11/7 14:52
* @description :
* @modified By:
*/
public class ListNode<K,V> {
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public ListNode<K, V> getPrev() {
return prev;
}
public void setPrev(ListNode<K, V> prev) {
this.prev = prev;
}
public ListNode<K, V> getNext() {
return next;
}
public void setNext(ListNode<K, V> next) {
this.next = next;
}
@Override
public String toString() {
return "ListNode(key=" + this.getKey() + ", value=" + this.getValue() + ", prev=" + this.getPrev() + ", next=" + this.getNext() + ")";
}
/**
* 索引key
*/
private K key;
/**
* 数据
*/
private V value;
/**
* 上一个节点
*/
private ListNode<K,V> prev;
/**
* 下一个节点
*/
private ListNode<K,V> next;
public ListNode(K key,V value)
{
this.key =key;
this.value =value;
}
public ListNode()
{
}
}
LRU算法实现类
import com.linwl.lrudemo.entity.ListNode;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author :linwl
* @date :Created in 2019/11/7 14:57
* @description :
* @modified By:
*/
public class LRUCache<V> {
/**
* 容量
*/
private int capacity =1024;
/**
* 节点记录表
*/
private Map<String, ListNode<String, V>> table = new ConcurrentHashMap<>();
/**
* 双向链表头部
*/
private ListNode<String,V> head;
/**
* 双向链表尾部
*/
private ListNode<String,V> tail;
public LRUCache(int capacity)
{
this();
this.capacity =capacity;
}
public LRUCache()
{
head =new ListNode<>();
tail =new ListNode<>();
head.setNext(tail);
head.setPrev(null);
tail.setPrev(head);
tail.setNext(null);
}
public V get(String key)
{
ListNode<String,V> node = table.get(key);
//缓存不存在
if(node == null)
{
return null;
}
//如果存在,则需要移动Node节点到表头
//截断node
node.getPrev().setNext(node.getNext());
node.getNext().setPrev(node.getPrev());
//移动到表头
node.setNext(head.getNext());
node.setPrev(head);
head.getNext().setPrev(node);
head.setNext(node);
table.put(key,node);
return node.getValue();
}
public void put(String key,V value)
{
ListNode<String, V> node = table.get(key);
//如果Node不在表中,代表缓存中并没有
if (node == null) {
if(table.size() == capacity)
{
//超容量了,移除尾部缓存
table.remove(tail.getPrev().getKey());
tail.setPrev(tail.getPrev().getPrev());
tail.setNext(null);
}
node =new ListNode<>(key,value);
table.put(key,node);
}
//移动Node节点到表头
node.setNext(head.getNext());
head.getNext().setPrev(node);
node.setPrev(head);
head.setNext(node);
}
}
使用效果
public static void main(String[] args)
{
LRUCache<ListNode> cache = new LRUCache<>(4);
ListNode<String, Integer> node1 = new ListNode<>("key1", 1);
ListNode<String, Integer> node2 = new ListNode<>("key2", 2);
ListNode<String, Integer> node3 = new ListNode<>("key3", 3);
ListNode<String, Integer> node4 = new ListNode<>("key4", 4);
ListNode<String, Integer> node5 = new ListNode<>("key5", 5);
ListNode<String, Integer> node6 = new ListNode<>("key6", 6);
cache.put("key1", node1);
cache.put("key2", node2);
cache.put("key3", node3);
cache.put("key4", node4);
System.out.println(cache.get("key2"));
cache.put("key5", node5);
System.out.println(cache.get("key1"));
cache.put("key6", node6);
System.out.println(cache.get("key3"));
System.out.println(cache.get("key2"));
System.out.println(cache.get("key6"));
}