LRU(最近最少使用)算法的简单应用实现 ——针对内存的使用情况,防止缓存的溢出问题。
import java.util.HashMap;
//LRU(最近最少使用)算法的简单应用实现——针对内存的使用情况,防止缓存的溢出问题。
//数据结构为--->具有链表功能的哈希表(哈希链表),而且是双向链表。
public class LRUCache {
private Node head;
private Node end;
private int limit;//缓存区大小,初始化时自行设置大小。
private HashMap<String, Node> hashmap; //哈希链表-->哈希表里应用链表内容
class Node{ //链表节点类
public Node pre;
public Node next;
public String key;
public String value;
public Node(String key,String value) {
this.key=key;
this.value=value;
}
}
public LRUCache(int limit) {
this.limit=limit;
hashmap=new HashMap<String,Node>();
}
//node节点的添加,一般添加到链表的最后出,即end节点的后边,完成添加后要将end节点指向当前添加完的node节点。
public void addNode(Node node) {
if(head==null) { //链表为空时,也就是第一个节点
head=node;
end=node;
}
else
{
end.next=node;
node.pre=end;
node.next=null;
end=node;
}
}
//删除当前node节点,考虑清楚node所处链表中的位置即可--->链表头部,链表尾部,链表中间,以及是否为当前链表中唯一的节点。
public String removeNode(Node node) {
if(head==node && end==node) { //链表里只有一个节点
head=null;
end=null;
}else if(head==node) { //删除头节点
head=head.next;
head.pre=null;
}else if(end==node) { //删除尾节点
end=end.pre;
end.next=null;
}else { //删除中间节点
node.pre.next=node.next;
node.next.pre=node.pre;
}
return node.key;
}
//先判断当前节点是否在链表尾部,如果是的话就不用刷新链表了,否则先删除当前节点,再重新添加到链表尾部即可。
public void refreshNode(Node node) {
if(end==node) { //如果是尾节点,不用操作直接返回。
return;
}
removeNode(node);
addNode(node);
}
//获取hashmap中的对象,每用一次就要刷新链表,将当前节点置于链表结尾处。
public String get(String key) {
Node node=hashmap.get(key);
if(node==null) { //不存在这个key对应的node,返回空。
return null;
}
refreshNode(node); //否则刷新这个节点置链表尾部
return node.value;
}
//向hashmap中放入新的对象,要判断当前对象是否已经存在,如果存在就跟新节点的值并刷新链表,否则添加新的hashmap对象-->
//这时要考虑缓存是否已满的问题,如果已满就要先删除链表的头节点,再添加新的节点进入链表,最后添加进hashmap哈希表中。
public void put(String key,String value) {
Node node=hashmap.get(key);
if(node==null) { //当前hashmap中没有这个元素,插入这个元素到hashmap中。
if(hashmap.size()>=limit) { //如果缓冲区已经满了,删除头节点。
String oldkey=removeNode(head);
hashmap.remove(oldkey);
}
//将元素插入到hashmap中
node=new Node(key,value);
addNode(node);
hashmap.put(key, node);
}
else
{ //hashmap中存在这个元素,更改value值,并把当前元素置于链表尾部。
node.value=value;
refreshNode(node);
}
}
//删除hashmap哈希表中的对象,先删除node链表中的当前node节点。
public void remove(String key) {
Node node=hashmap.get(key);
removeNode(node);//在链表中将节点删除
hashmap.remove(key);//在哈希表中将这个key对应的元素删除
}
public static void main(String[] args) {
// TODO Auto-generated method stub
LRUCache lruCache = new LRUCache(5);
lruCache.put("001", " 用户1信息");
lruCache.put("002", " 用户1信息");
lruCache.put("003", " 用户1信息");
lruCache.put("004", " 用户1信息");
lruCache.put("005", " 用户1信息");
lruCache.get("002");
lruCache.put("004", " 用户2信息更新");
lruCache.put("006", " 用户6信息");
System.out.println(lruCache.get("001"));
System.out.println(lruCache.get("006"));
}
}