LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。
本质就是哈希表+双向链表来完成的,并且时间复杂度是O(1)也就是最快的方式.
下面两种方式我参考学习来,在此做个记录直接上代码
第一种:
package com.gm.wj.demo;
import java.util.LinkedHashMap;
import java.util.Map;
public class LRUDemoLinkedHashMap<K,V> extends LinkedHashMap<K,V> {
static private float load_factor = 0.75f;
private int initialCapacity;
public LRUDemoLinkedHashMap(int initialCapacity){
super(initialCapacity,load_factor,false);
this.initialCapacity=initialCapacity;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return super.size() > 4;
}
public static void main(String[] args) {
LRUDemoLinkedHashMap kvlruDemo = new LRUDemoLinkedHashMap(4);
kvlruDemo.put("1", 1);
kvlruDemo.put("2", 1);
kvlruDemo.put("3", 1);
kvlruDemo.put("4", 1);
kvlruDemo.put("7", 1);
kvlruDemo.put("8", 1);
kvlruDemo.get("4");
kvlruDemo.get("4");
kvlruDemo.put("x",1);
System.out.println(kvlruDemo.keySet());
}
}
第二种:
package com.gm.wj.demo;
import java.util.HashMap;
import java.util.Map;
public class HandwrittenLRUDemo {
class Node<K,V>{
K key;
V value;
Node<K,V> prev;
Node<K,V> next;
public Node(){
this.prev =this.next = null;
}
public Node(K key,V value){
this.key = key;
this.value = value;
this.prev =this.next = null;
}
}
class bidirectionalLinkedList<K,V>{
Node<K,V> head;
Node<K,V> tail;
public bidirectionalLinkedList(){
head = new Node<>();
tail = new Node<>();
head.next =tail;
tail.prev = head;
}
public void addHead(Node<K,V> node){
node.prev = head;
node.next = head.next;
head.next.prev = node;
head.next = node;
}
public void removeNode(Node<K,V> node){
node.next.prev = node.prev;
node.prev.next = node.next;
node.prev = null;
node.next = null;
}
public Node<K,V> getLast(){
return tail.prev;
}
}
private int initialCapacity;
Map<Object,Node<Object,Object>> map;
bidirectionalLinkedList<Object,Object> bidirectionalLinkedList;
public HandwrittenLRUDemo(int initialCapacity){
this.initialCapacity = initialCapacity;
map = new HashMap<>();
bidirectionalLinkedList = new bidirectionalLinkedList<>();
}
public Object get(Object key){
if (!map.containsKey(key)){
return -1;
}else {
Node<Object, Object> node = map.get(key);
bidirectionalLinkedList.removeNode(node);
bidirectionalLinkedList.addHead(node);
return node.value;
}
}
public void put(Object key,Object value){
if (map.containsKey(key)){
Node<Object, Object> node = map.get(key);
node.value = value;
map.put(key,node);
bidirectionalLinkedList.removeNode(node);
bidirectionalLinkedList.addHead(node);
}else {
if (map.size() == initialCapacity){
Node<Object, Object> lastNode = bidirectionalLinkedList.getLast();
bidirectionalLinkedList.removeNode(lastNode);
map.remove(lastNode.key);
}
}
Node<Object, Object> newNode = new Node<>(key,value);
map.put(key,newNode);
bidirectionalLinkedList.addHead(newNode);
}
public static void main(String[] args) {
HandwrittenLRUDemo kvlruDemo = new HandwrittenLRUDemo(4);
kvlruDemo.put("1", 1);
kvlruDemo.put("2", 1);
kvlruDemo.put("3", 1);
kvlruDemo.put("4", 1);
kvlruDemo.put("7", 1);
kvlruDemo.put("8", 1);
kvlruDemo.get("4");
kvlruDemo.get("4");
kvlruDemo.put("x",1);
System.out.println(kvlruDemo.map.keySet());
}
}
|