LRU算法

  1 package com.daoyouzhu;
  2 
  3 import java.util.Hashtable;
  4 import java.util.Map;
  5 
  6 /**
  7  * LRU 最近未使用删除
  8  * 核心思想:1.需要一个数据载体类,来存放
  9  *         2.需要一个操作载体类的方法,用来完成数据的添加删除等
 10  *         3.我需要维护一个hashMap,来判断是否存在数据
 11  *  个人认为,对于链表的操作,特别是新节点加入到链表里或者删除,操作前后指向,从本节点开始
 12  */
 13 public class RedisLRUDemo {
 14     class Node<K, V> {
 15         K key;
 16         V value;
 17         Node<K, V> prev;
 18         Node<K, V> next;
 19 
 20         public Node() {
 21             prev = next = null;
 22         }
 23 
 24         public Node(K key, V value) {
 25             this.key = key;
 26             this.value = value;
 27             prev = next = null;
 28         }
 29     }
 30 
 31     class DoubleLinkedDemo<K, V> {
 32         Node<K, V> head;
 33         Node<K, V> tail;
 34 
 35         public DoubleLinkedDemo() {
 36             head = new Node<>();
 37             tail = new Node<>();
 38             head.next = tail;
 39             tail.prev = head;
 40         }
 41 
 42         public void addHead(Node<K, V> node) {
 43             node.prev = head;
 44             node.next = head.next;
 45             head.next.prev = node;
 46             head.next = node;
 47         }
 48 
 49         public void delTail(Node<K, V> node) {
 50             node.prev.next = node.next;
 51             node.next.prev = node.prev;
 52             node.prev = null;
 53             node.next = null;
 54         }
 55 
 56         public Node<K, V> getLast() {
 57             return tail.prev;
 58         }
 59     }
 60 
 61     DoubleLinkedDemo<Integer, Integer> doubleLinkedDemo;
 62     Map<Integer, Node<Integer, Integer>> map;
 63     private int size;
 64 
 65     public RedisLRUDemo(int size) {
 66         this.size = size;
 67         doubleLinkedDemo = new DoubleLinkedDemo<>();
 68         map = new Hashtable<>();
 69     }
 70 
 71     public int get(int key) {
 72         if (!map.containsKey(key)) {
 73             return -1;
 74         }
 75         Node<Integer, Integer> node = map.get(key);
 76         doubleLinkedDemo.delTail(node);
 77         doubleLinkedDemo.addHead(node);
 78         return node.value;
 79     }
 80 
 81     public void put(int key, int value) {
 82         if (map.containsKey(key)) {
 83             Node<Integer, Integer> node = map.get(key);
 84             doubleLinkedDemo.delTail(node);
 85             node.value = value;
 86             doubleLinkedDemo.addHead(node);
 87             map.put(key, node);
 88         } else {
 89             if (size == map.size()) {//满了
 90                 Node<Integer, Integer> lastNode = doubleLinkedDemo.getLast();
 91                 map.remove(lastNode.key);
 92                 doubleLinkedDemo.delTail(lastNode);
 93             }
 94             Node<Integer, Integer> newNode = new Node<>(key, value);
 95             map.put(key, newNode);
 96             doubleLinkedDemo.addHead(newNode);
 97         }
 98     }
 99 
100     public static void main(String[] args) {
101         RedisLRUDemo redisLRUDemo = new RedisLRUDemo(3);
102         redisLRUDemo.put(1, 1);
103         redisLRUDemo.put(2, 2);
104         redisLRUDemo.put(3, 3);
105         System.out.println(redisLRUDemo.map.keySet());
106 
107         redisLRUDemo.put(4, 1);
108         System.out.println(redisLRUDemo.map.keySet());
109 
110         redisLRUDemo.put(3, 1);
111         System.out.println(redisLRUDemo.map.keySet());
112         redisLRUDemo.put(3, 1);
113         System.out.println(redisLRUDemo.map.keySet());
114         redisLRUDemo.put(3, 1);
115         System.out.println(redisLRUDemo.map.keySet());
116         redisLRUDemo.put(5, 1);
117         System.out.println(redisLRUDemo.map.keySet());
118 
119         System.out.println(redisLRUDemo.doubleLinkedDemo.head);
120     }
121 
122 }

 执行结果: 

 

 流程图1:

 

流程图2:

 

 

 描述:如果有ABC三个在队列中,顺序也是head->A->B->C->tail,如果又访问了一次C,就需要将C放在head的后面,将AB后移,顺序变为head->C->A->B->tail,所以要将原来的C删除,新增一个C放在head后,

如果又新来了一个D,那么B就应该被删除,将D放在head后,顺序为head->D->C->A->tail。类似于AQS的底层实现。

 

posted @ 2021-07-22 17:14  诸道游  阅读(75)  评论(0)    收藏  举报