1. class LRUCache {
    2. //双线链表的节点类
    3. class DoublyListNode {
    4. public int key;
    5. public int val;
    6. public DoublyListNode pre;
    7. public DoublyListNode next;
    8. public DoublyListNode() {}
    9. public DoublyListNode(int val) { this.val = val; }
    10. }
    11. //双相链表的头节点
    12. private DoublyListNode head;
    13. //双线链表的尾结点
    14. private DoublyListNode tail;
    15. //维护索引的Map
    16. Map<Integer,DoublyListNode> map;
    17. //大小
    18. int capacity;
    19. public LRUCache(int capacity) {
    20. //保存大小
    21. this.capacity = capacity;
    22. //链表头尾节点初始化,然后头尾相连形成双链表结构
    23. head = new DoublyListNode();
    24. tail = new DoublyListNode();
    25. head.next = tail;
    26. tail.pre = head;
    27. //初始化索引MAp
    28. map = new HashMap<>();
    29. }
    30. public int get(int key) {
    31. //如果map里面没有就直接返回-1
    32. if(!map.containsKey(key)){
    33. return -1;
    34. }
    35. DoublyListNode node = map.get(key);
    36. //从中间移除node
    37. doublyListNodeRemove(node);
    38. // 再 从头部插入node
    39. doublyListNodeInsert(head,node);
    40. return node.val;
    41. }
    42. public void put(int key, int value) {
    43. //如果map里不存在这个key
    44. if(!map.containsKey(key)){
    45. DoublyListNode node = new DoublyListNode();
    46. node.key = key;
    47. node.val = value;
    48. //保存hashMap
    49. map.put(key,node);
    50. //从头部插入链表
    51. doublyListNodeInsert(head,node);
    52. //如果超过最大长度限制了,则删除链表尾部最后一个节点,删除最后一个节点的hashMap的缓存
    53. if(map.size() > capacity){
    54. //清掉map的缓存,tail的pre的key
    55. map.remove(tail.pre.key);
    56. //删除尾部最后一个节点,也就是tald的pre
    57. doublyListNodeRemove(tail.pre);
    58. }
    59. }else {
    60. //如果存在MAP里了,就更新这个值,然在在链表中删掉,放入开头插入
    61. DoublyListNode node = map.get(key);
    62. node.val = value;
    63. //从中间移除node
    64. doublyListNodeRemove(node);
    65. // 再 从头部插入node
    66. doublyListNodeInsert(head,node);
    67. }
    68. }
    69. /**
    70. * 双向链表删除一个node(从中间直接删掉)
    71. * @param node
    72. */
    73. public void doublyListNodeRemove(DoublyListNode node){
    74. node.pre.next = node.next;
    75. node.next.pre = node.pre;
    76. }
    77. /**
    78. * 双向链表。在P后面插入一个节点
    79. * @param p
    80. * @param node
    81. */
    82. public void doublyListNodeInsert(DoublyListNode p ,DoublyListNode node){
    83. //node 和 p的next建立联系
    84. p.next.pre = node;
    85. node.next = p.next;
    86. // node 和 p 建立联系
    87. p.next = node;
    88. node.pre = p;
    89. }
    90. }