LRUCache.java 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package cn.minbb.iot.util;
  2. import java.util.HashMap;
  3. // 链表 + HashMap 容器实现
  4. public class LRUCache<K, V> {
  5. private int cacheCapacity;
  6. private HashMap<K, CacheNode> caches;
  7. private CacheNode first;
  8. private CacheNode last;
  9. public LRUCache(int size) {
  10. this.cacheCapacity = size;
  11. caches = new HashMap<>(size);
  12. }
  13. public synchronized void put(K k, V v) {
  14. CacheNode node = caches.get(k);
  15. if (node == null) {
  16. if (caches.size() >= cacheCapacity) {
  17. caches.remove(last.key);
  18. removeLast();
  19. }
  20. node = new CacheNode();
  21. node.key = k;
  22. }
  23. node.value = v;
  24. moveToFirst(node);
  25. caches.put(k, node);
  26. }
  27. public synchronized Object get(K k) {
  28. CacheNode node = caches.get(k);
  29. if (node == null) {
  30. return null;
  31. }
  32. moveToFirst(node);
  33. return node.value;
  34. }
  35. public synchronized Object remove(K k) {
  36. CacheNode node = caches.get(k);
  37. if (node != null) {
  38. if (node.pre != null) {
  39. node.pre.next = node.next;
  40. }
  41. if (node.next != null) {
  42. node.next.pre = node.pre;
  43. }
  44. if (node == first) {
  45. first = node.next;
  46. }
  47. if (node == last) {
  48. last = node.pre;
  49. }
  50. }
  51. return caches.remove(k);
  52. }
  53. public synchronized void clear() {
  54. first = null;
  55. last = null;
  56. caches.clear();
  57. }
  58. private void moveToFirst(CacheNode node) {
  59. if (first == node) {
  60. return;
  61. }
  62. if (node.next != null) {
  63. node.next.pre = node.pre;
  64. }
  65. if (node.pre != null) {
  66. node.pre.next = node.next;
  67. }
  68. if (node == last) {
  69. last = last.pre;
  70. }
  71. if (first == null || last == null) {
  72. first = last = node;
  73. return;
  74. }
  75. node.next = first;
  76. first.pre = node;
  77. first = node;
  78. first.pre = null;
  79. }
  80. private void removeLast() {
  81. if (last != null) {
  82. last = last.pre;
  83. if (last == null) {
  84. first = null;
  85. } else {
  86. last.next = null;
  87. }
  88. }
  89. }
  90. @Override
  91. public String toString() {
  92. StringBuilder sb = new StringBuilder();
  93. CacheNode node = first;
  94. while (node != null) {
  95. sb.append(String.format("%s:%s ", node.key, node.value));
  96. node = node.next;
  97. }
  98. return sb.toString();
  99. }
  100. class CacheNode {
  101. CacheNode pre;
  102. CacheNode next;
  103. Object key;
  104. Object value;
  105. CacheNode() {
  106. // 无参构造
  107. }
  108. }
  109. }