1 public class LRUCache {
2
3 private int capacity;
4 private Map<Integer, Entry> nodes;
5 private int currentSize;
6 private Entry first;
7 private Entry last;
8
9 public LRUCache(int capacity) {
10 this.capacity = capacity;
11 currentSize = 0;
12 nodes = new HashMap<Integer, Entry>();
13 }
14
15 public int get(int key) {
16 Entry node = nodes.get(key);
17 if(node != null){
18 moveToHead(node);
19 return node.value;
20 } else {
21 return -1;
22 }
23 }
24
25 public void set(int key, int value) {
26 Entry node = nodes.get(key);
27 if(node == null){
28 if(currentSize >= capacity){
29 nodes.remove(last.key);
30 removeLast();
31 } else {
32 currentSize ++;
33 }
34 node = new Entry();
35 }
36
37 if(currentSize == 1){
38 first = node;
39 last = node;
40 }
41
42 node.key = key;
43 node.value = value;
44 moveToHead(node);
45 nodes.put(key, node);
46 }
47
48 private void moveToHead(Entry node){
49 if(node == first)
50 return;
51
52 // delete current node from doubly linked list
53 if(node.pre != null){
54 node.pre.next = node.next;
55 }
56 if(node.next != null){
57 node.next.pre = node.pre;
58 }
59
60 if(last == node){
61 last = node.pre;
62 }
63
64 if(first != null){
65 node.next = first;
66 first.pre = node;
67 }
68 first = node;
69 node.pre = null;
70
71 }
72
73 private void removeLast(){
74 if(last != null){
75 if(last.pre != null){
76 last.pre.next = null;
77 } else {
78 first = null;
79 }
80 last = last.pre;
81 }
82 }
83 }
84
85 class Entry{
86 Entry pre;
87 Entry next;
88 int key;
89 int value;
90 }