| 13 | |
| 14 | |
| 15 | public class LRUCache { |
| 16 | public int capacity; |
| 17 | public HashMap<Integer, DoublyLinkedListNode> cache; |
| 18 | public DoublyLinkedListNode head; |
| 19 | public DoublyLinkedListNode tail; |
| 20 | public LRUCache(int capacity) { |
| 21 | this.capacity = capacity; |
| 22 | // A hash map that maps keys to nodes. |
| 23 | cache = new HashMap<>(); |
| 24 | // Initialize the head and tail dummy nodes and connect them to |
| 25 | // each other to establish a basic two-node doubly linked list. |
| 26 | head = new DoublyLinkedListNode(-1, -1); |
| 27 | tail = new DoublyLinkedListNode(-1, -1); |
| 28 | head.next = tail; |
| 29 | tail.prev = head; |
| 30 | } |
| 31 | |
| 32 | public int get(int key) { |
| 33 | if (!cache.containsKey(key)) { |
| 34 | return -1; |
| 35 | } |
| 36 | else { |
| 37 | // To make this key the most recently used, remove its node and |
| 38 | // re-add it to the tail of the linked list. |
| 39 | remove(cache.get(key)); |
| 40 | addToTail(cache.get(key)); |
| 41 | return cache.get(key).val; |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | public void put(int key, int val) { |
| 46 | // If a node with this key already exists, remove it from the |
| 47 | // linked list. |
| 48 | if (cache.containsKey(key)) { |
| 49 | remove(cache.get(key)); |
| 50 | } |
| 51 | DoublyLinkedListNode node = new DoublyLinkedListNode(key, val); |
| 52 | cache.put(key, node); |
| 53 | // Remove the least recently used node from the cache if adding |
| 54 | // this new node will result in an overflow. |
| 55 | if (cache.size() > capacity) { |
| 56 | cache.remove(head.next.key); |
| 57 | remove(head.next); |
| 58 | } |
| 59 | addToTail(node); |
| 60 | } |
| 61 | |
| 62 | private void addToTail(DoublyLinkedListNode node) { |
| 63 | DoublyLinkedListNode prevNode = tail.prev; |
| 64 | node.prev = prevNode; |
| 65 | node.next = tail; |
| 66 | prevNode.next = node; |
| 67 | tail.prev = node; |
| 68 | } |
| 69 | |
| 70 | private void remove(DoublyLinkedListNode node) { |
| 71 | node.prev.next = node.next; |
| 72 | node.next.prev = node.prev; |
nothing calls this directly
no outgoing calls
no test coverage detected