更多文章,欢迎关注微信公众号:深夜程猿java
在上一篇文章简单聊聊了LRU算法理论篇,这里就和你们使用单链表实现一个简单的LRU算法。其它类型的实现同样的思路,只不过是处理的复杂程度不同而已。node
Node.java:存储数据的结点算法
package lru;
/**
* @author wu
* @since 2019/4/2
*/
public class Node<K, V> {
private V data;
private K key;
/**
* 指针,指向下一节点
*/
private Node<K, V> next;
public V getData() {
return data;
}
public void setData(V data) {
this.data = data;
}
public Node<K, V> getNext() {
return next;
}
public void setNext(Node<K, V> next) {
this.next = next;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
}
复制代码
LinkedLru.java:LRU实现json
package lru;
/**
* @author wu
* @since 2019/4/2
*/
public class LinkedLru<K, V> {
private Node<K, V> root;
private int maxCapacity;
private int defaultCapacity = 10;
public LinkedLru(int maxCapacity) {
if (maxCapacity <= 0) {
throw new IllegalArgumentException("maxCapacity should not less than 0");
}
this.maxCapacity = maxCapacity;
}
public int getMaxCapacity() {
return maxCapacity;
}
public LinkedLru() {
this.maxCapacity = defaultCapacity;
}
public Node<K, V> get(K key) {
if (key == null) {
throw new IllegalArgumentException("key should not be null");
}
if (root == null) {
return null;
}
Node<K, V> temp = root;
while (temp != null) {
if (key.equals(temp.getKey())) {
Node<K, V> node = new Node<>();
node.setData(temp.getData());
node.setKey(temp.getKey());
return node;
}
temp = temp.getNext();
}
return null;
}
public boolean add(Node<K, V> data) {
if (data == null) {
throw new IllegalArgumentException("can not cache null");
}
if (root == null) {
root = data;
return true;
} else {
Node<K, V> prev = root;
Node<K, V> next = root.getNext();
Node<K, V> header = root;
Node<K, V> cursor;
int index = 1;
while (true) {
index++;
cursor = prev;
if (index >= getMaxCapacity()) {
// 设置data为头部结点
data.setNext(header);
root = data;
// 缓存达到最大值,淘汰数据,此时prev就是尾部结点
cursor.setNext(null);
break;
}
if (next == null) {
// 容量没有达到最大,已到缓存尾部,而且数据尚未缓存过
data.setNext(header);
root = data;
cursor.setNext(null);
break;
}
if (next.getKey() == data.getKey()) {
// 数据存在,交换指针,数据放在首部
data.setNext(header);
prev.setNext(next.getNext());
root = data;
break;
}
prev = next;
next = next.getNext();
}
}
return true;
}
public Node<K, V> getRoot() {
return root;
}
}
复制代码
测试类:缓存
package lru;
import com.alibaba.fastjson.JSON;
/**
* @author wu
* @since 2019/4/3
*/
public class Test {
public static void main(String[] args) {
LinkedLru<String, String> cache = new LinkedLru<>(10);
int pos = 0;
while (pos < 100) {
pos++;
Node<String, String> node = new Node();
node.setKey("key:" + pos);
node.setData("data:" + pos);
cache.add(node);
}
System.out.println(JSON.toJSONString(cache.getRoot()));
System.out.println(JSON.toJSONString(cache.get("key:10")));
System.out.println(JSON.toJSONString(cache.get("key:100")));
}
}
复制代码
输出:bash
{"data":"data:100","key":"key:100","next":{"data":"data:99","key":"key:99","next":{"data":"data:98","key":"key:98","next":{"data":"data:97","key":"key:97","next":{"data":"data:96","key":"key:96","next":{"data":"data:95","key":"key:95","next":{"data":"data:94","key":"key:94","next":{"data":"data:93","key":"key:93","next":{"data":"data:92","key":"key:92","next":{"data":"data:91","key":"key:91"}}}}}}}}}}
null
{"data":"data:100","key":"key:100"}
复制代码
数据结构系列之LRU算法理论篇数据结构