1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
| class LRUCache { private final int capacity; private final Map<Integer, Node> map; private final Node head; private Node tail;
public LRUCache(int capacity) { this.capacity = capacity; head = new Node(0, 0, null, null); map = new HashMap<>(capacity); }
public int get(int key) { Node node = getNode(key); if (node == null) { return -1; } return node.value; }
private Node getNode(int key) { Node node = map.get(key); if (node == null) { return null; } moveHead(node); return node; }
private void moveHead(Node node) { if (node != head.next) { Node prev = node.prev; Node next = node.next;
if (node == tail) { tail = node.prev; } else { next.prev = node.prev; }
node.prev = head; prev.next = next;
node.next = head.next; head.next.prev = node; head.next = node; } }
public void put(int key, int value) { Node node = getNode(key); if (node == null) { node = new Node(key, value, head, head.next); if (head.next != null) { head.next.prev = node; } head.next = node;
if (tail == null) { tail = node; }
map.put(key, node);
if (map.size() > capacity) { evict(); } } else { node.value = value; } }
public boolean evict() { if (tail != null) { map.remove(tail.key); tail.prev.next = null; tail = tail.prev == head ? null: tail.prev; return true; } return false; }
private static class Node { int key; int value; Node prev; Node next;
public Node(int key, int value, Node prev, Node next) { this.key = key; this.value = value; this.prev = prev; this.next = next; }
public String toString() { return String.format("[%d, prev=%d, next=%s]", key, prev == null ? null : prev.value, next); } }
public String toString() { return String.format("--- \nhead=%s\ntail=%s\n--- ", head, tail); }
}
|