网上说了很多linkhashmap的实现,但是我觉得还是不要用jdk的工具,自己用最原始的方式实现才更有利于理解。 public class Lru { private static final int MAX_NUM = 3; //用来记录节点,使得遍历链表复杂度降低到O(1) private static ConcurrentHashMap<String, Link.Entry> tmpMap = new ConcurrentHashMap<>(MAX_NUM); private static Link link = new Link(); public static String get(String key) { Link.Entry entry = tmpMap.get(key); link.remove(entry); link.insertFirst(entry); return entry.value; } public static void put(String key, String value) { if (tmpMap.containsKey(key)) { link.remove(tmpMap.get(key)); link.insertFirst(tmpMap.get(key)); return; } if (tmpMap.size() >= MAX_NUM) { link.remove(link.tail.before); } Link.Entry entry = link.new Entry(null, null, key, value); link.insertFirst(entry); tmpMap.put(key, entry); } public static void main(String[] args) { Lru.put("1", "a"); Lru.put("2", "b"); Lru.put("3", "c"); Lru.put("4", "d"); Lru.put("2", "b"); Link.Entry entry = link.head.after; while (entry.after != null) { System.out.println("key: " + entry.key + " value: " + entry.value); entry = entry.after; } } } //双向链表 class Link { Entry head; Entry tail; public Link() { head = new Entry(); tail = new Entry(); head.setAfter(tail); tail.setBefore(head); } @Setter @Getter @NoArgsConstructor @AllArgsConstructor class Entry { Entry before; Entry after; String key; String value; } //此部分比较麻烦,由于是双向链表所以,修改指针时候要注意前后节点都要修改 public void insertFirst(Entry entry) { entry.after = head.after; entry.after.before = entry; entry.before = head; head.after = entry; if (tail.before == head) { tail.before = entry; } } public void remove(Entry entry) { entry.before.after = entry.after; entry.after.before = entry.before; } }
java实现lru
最新推荐文章于 2021-12-28 21:48:55 发布