/** * @Author: subd * @Date: 2019/8/28 8:22 * LRU * 末尾淘汰算法 线程不安全 * 手写linkedHashMap 进行书写 */ public class LRU { private Node head; private Node end; //缓存上限设置 private int limit; private HashMap<String, Node> hashMap; public LRU(int limit) { this.limit = limit; this.hashMap = new HashMap<>(); } public String get(String key) { Node node = hashMap.get(key); if (node == null) { return null; } refreshNode(node); return node.value; } public void put(String key, String value) { Node node = hashMap.get(key); if (node == null) { //如果key不存在,则插入key—value if (hashMap.size() >= limit) { String oldKey = removeNode(head); hashMap.remove(oldKey); } node = new Node(key, value); addNode(node); hashMap.put(key, node); } else { //如果key存在,则刷新Key-Value node.value = value; refreshNode(node); } } private void remove(String key) { Node node = hashMap.get(key); removeNode(node); hashMap.remove(key); } /** * 刷新被访问节点的位置 * * @param node * @return */ private void refreshNode(Node node) { //如果访问的是尾节点,则无需移动节点 if (node == end) { return; } //移除节点 removeNode(node); //重新插入节点 addNode(node); } /** * 删除节点 * * @param node * @return */ private String removeNode(Node node) { if (node == head && node == end) { //移除唯一节点 head = null; end = null; } else if (node == end) { //移除尾节点 end = end.pre; end.next = null; } else if (node == head) { //移除头节点 head = head.next; head.pre = null; } else { //移除中间节点 node.pre.next = node.next; node.next.pre = node.pre; } return node.key; } /** * 尾部插入节点 * * @param node */ private void addNode(Node node) { if (end != null) { end.next = node; node.pre = end; node.next = null; } end = node; if (head == null) { head = node; } } /** * 节点类 */ public class Node { public Node pre; public Node next; public String key; public String value; public Node(String key, String value) { this.key = key; this.value = value; } } public static void main(String[] args) { LRU lru = new LRU(5); lru.put("001","用户1信息"); lru.put("002","用户2信息"); lru.put("003","用户3信息"); lru.put("004","用户4信息"); lru.put("005","用户5信息"); lru.get("002"); lru.put("004","用户2信息更新"); lru.put("006","用户6信息更新"); System.out.println(lru.get("001")); System.out.println(lru.get("006")); } }