public class LruCached<K, V> {
class Node<K, V> {
K key;
V value;
Node<K, V> pre;
Node<K, V> next;
public Node() {
this.next = this.pre = null;
}
public Node(K key, V value) {
this.key = key;
this.value = value;
this.pre = this.next = null;
}
}
class DoubleLinkedList<K, V> {
Node head;
Node tail;
public DoubleLinkedList() {
this.head = new Node();
this.tail = new Node();
this.head.next = tail;
this.tail.pre = head;
}
public void addHead(Node node) {
node.next = head.next;
node.pre = head;
head.next = node;
node.next.pre = node;
}
public void removeNode(Node node) {
node.next.pre = node.pre;
node.pre.next = node.next;
node.next = null;
node.pre = null;
}
public Node getLastNode() {
return tail.pre;
}
}
Map<K, Node<K, V>> map = null;
DoubleLinkedList doubleLinkedList = null;
int cacheSize;
public LruCached(int cacheSize) {
this.cacheSize = cacheSize;
map = new HashMap<>();
doubleLinkedList = new DoubleLinkedList();
}
public void put(K key, V value) {
if (map.containsKey(key)) {
Node<K, V> node = map.get(key);
node.value = value;
map.put(key, node);
doubleLinkedList.removeNode(node);
doubleLinkedList.addHead(node);
} else {
if (map.size() == cacheSize) {
Node lastNode = doubleLinkedList.getLastNode();
map.remove(lastNode.key);
doubleLinkedList.removeNode(lastNode);
}
Node node = new Node(key, value);
doubleLinkedList.addHead(node);
map.put(key, node);
}
}
public Object get(K key){
if (!map.containsKey(key)){
return -1;
}
Node<K, V> node = map.get(key);
doubleLinkedList.removeNode(node);
doubleLinkedList.addHead(node);
return node.value;
}
public static void main(String[] args) {
LruCached lruCached = new LruCached(3);
lruCached.put(1, 1);
lruCached.put(2, 2);
lruCached.put(3, 3);
System.out.println(lruCached.map.keySet());
lruCached.put(4, 4);
System.out.println(lruCached.map.keySet());
lruCached.put(5, 5);
System.out.println(lruCached.map.keySet());
lruCached.put(1, 1);
System.out.println(lruCached.map.keySet());
}
}