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 }