https://leetcode-cn.com/problems/lru-cache/

    1. public class LRUCache extends LinkedHashMap<Integer, Integer> {
    2. private int capacity;
    3. public LRUCache(int capacity) {
    4. super(capacity, 0.75f, true);
    5. this.capacity = capacity;
    6. }
    7. public int get(int key) {
    8. // 访问数据的 get 方法
    9. return super.get(key) == null ? -1 : super.get(key);
    10. }
    11. public void put(int key, int value) {
    12. //
    13. super.put(key, value);
    14. }
    15. @Override
    16. protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
    17. return size() > capacity;
    18. }
    19. }

    78157770193ef9ecf5f7b9dfadc803f.jpg

    1. public class LRUCache {
    2. // 首先定义一个双向链表的节点类
    3. class Node {
    4. int key;
    5. int val;
    6. Node next;
    7. Node prev;
    8. public Node() {
    9. }
    10. public Node(int key, int val) {
    11. this.key = key;
    12. this.val = val;
    13. }
    14. }
    15. // 定义 HashMap
    16. private HashMap<Integer, Node> hashMap = new HashMap<Integer, Node>();
    17. // 定义基本属性
    18. private int capacity;
    19. // size 是已经有的、占用的大小,<= capacity
    20. private int size;
    21. // 定义头尾指针
    22. private Node head, tail;
    23. public LRUCache(int capacity) {
    24. this.capacity = capacity;
    25. this.size = 0;
    26. // 定义哨兵,方便统一处理
    27. head = new Node();
    28. tail = new Node();
    29. head.next = tail;
    30. tail.prev = head;
    31. }
    32. public int get(int key) {
    33. // 从 Hash 表中查找 key,不存在返回 -1
    34. Node node = hashMap.get(key);
    35. if (node == null) return -1;
    36. // 存在需要进行操作:将当前节点移到链表末尾
    37. moveToTail(node);
    38. return node.val;
    39. }
    40. private void moveToTail(Node node) {
    41. // 移动节点到末尾
    42. removeNode(node);
    43. addToTail(node);
    44. }
    45. private void addToTail(Node node) {
    46. // 在链表末尾增加一个节点
    47. // 全程只与末尾发生关系,使用前一个节点也是用 tail.prev
    48. node.next = tail;
    49. // 以原先的末尾节点作为前一个节点
    50. node.prev = tail.prev;
    51. tail.prev.next = node;
    52. tail.prev = node;
    53. }
    54. private void removeNode(Node node) {
    55. // 删除某一个节点:跳过该节点
    56. node.prev.next = node.next;
    57. node.next.prev = node.prev;
    58. }
    59. public void put(int key, int val) {
    60. // 从 Hash 表中查找 key,不存在返回 -1
    61. Node node = hashMap.get(key);
    62. if (node == null) {
    63. // 创建新的节点,插入末尾
    64. Node newNode = new Node(key, val);
    65. // 1. 保存进 Hash 表
    66. hashMap.put(key, newNode);
    67. // 2. 放到双向链表末尾
    68. addToTail(newNode);
    69. size++;
    70. // 3. 如果超出容量限制,删除链表头结点
    71. if (size > capacity) {
    72. Node head = removeHead();
    73. hashMap.remove(head.key);
    74. size--;
    75. }
    76. } else {
    77. // 存在,修改 val,并移到末尾
    78. node.val = val;
    79. moveToTail(node);
    80. }
    81. }
    82. private Node removeHead() {
    83. Node realHead = head.next;
    84. removeNode(realHead);
    85. return realHead;
    86. }
    87. }