| 10 | import java.util.HashMap; |
| 11 | |
| 12 | public class LRUCache { |
| 13 | private static class Node { |
| 14 | int key; |
| 15 | int value; |
| 16 | Node prev; |
| 17 | Node next; |
| 18 | |
| 19 | public Node(int key, int value) { |
| 20 | this.key = key; |
| 21 | this.value = value; |
| 22 | } |
| 23 | } |
| 24 | |
| 25 | private final int capacity; |
| 26 | private final HashMap<Integer, Node> map; |
| 27 | private final Node head; |
| 28 | private final Node tail; |
| 29 | |
| 30 | public LRUCache(int capacity) { |
| 31 | this.capacity = capacity; |
| 32 | map = new HashMap<>(); |
| 33 | head = new Node(0, 0); |
| 34 | tail = new Node(0, 0); |
| 35 | head.next = tail; |
| 36 | tail.prev = head; |
| 37 | } |
| 38 | |
| 39 | public int get(int key) { |
| 40 | if (!map.containsKey(key)) { |
| 41 | return -1; |
| 42 | } |
| 43 | Node node = map.get(key); |
| 44 | remove(node); |
| 45 | insertAtHead(node); |
| 46 | return node.value; |
| 47 | } |
| 48 | |
| 49 | public void put(int key, int value) { |
| 50 | if (map.containsKey(key)) { |
| 51 | Node node = map.get(key); |
| 52 | node.value = value; |
| 53 | remove(node); |
| 54 | insertAtHead(node); |
| 55 | } else { |
| 56 | if (map.size() == capacity) { |
| 57 | map.remove(tail.prev.key); |
| 58 | remove(tail.prev); |
| 59 | } |
| 60 | Node newNode = new Node(key, value); |
| 61 | map.put(key, newNode); |
| 62 | insertAtHead(newNode); |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | private void remove(Node node) { |
| 67 | node.prev.next = node.next; |
| 68 | node.next.prev = node.prev; |
| 69 | } |
nothing calls this directly
no outgoing calls
no test coverage detected