模拟采用链表保存缓存数据,功能如下
1. 新数据插入到链表头部;
2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部;
3. 当链表满的时候,将链表尾部的数据丢弃。
假设访问的数据为 Person
public class LRUCache{ private static int count=0; private int capacity; private static class Node{ private static Node head; private static Node tail; private Person person; private Node prev; private Node next; public Node(Person person){ this.person = person; } } public void iterator(){ Node h = Node.head; while (h!=null){ System.out.println(h.person.getId()+" "+h.person.getName()); h = h.next; } } public LRUCache(int capacity){ this.capacity = capacity; } public Person getPersonById(int id){ Node h = Node.head; if (h==null)return null; while (h!=null){ if (h.person.getId() == id){ Person target = h.person; moveToHead(h.person); deleteNode(h); return target; } h = h.next; } return null; } public void addToList(Person person){ if (capacity == count){ Node.tail = Node.tail.prev; Node.tail.next = null; } moveToHead(person); count++; } private void moveToHead(Person person){ if (Node.head == null){ Node newNode = new Node(person); Node.head = newNode; Node.tail = newNode; return; } Node h = Node.head; Node newNode = new Node(person); newNode.next = h; h.prev = newNode; Node.head = newNode; } private void deleteNode(Node node){ if (node == Node.head){ Node.head = node.next; Node.head.prev = null; } if (node == Node.tail){ Node.tail = node.prev; Node.tail.next = null; } node.prev.next = node.next; node.next.prev = node.prev; } }
模拟获取数据:
public class PersonList { private LRUCache cache; public PersonList(LRUCache lruCache){ this.cache = lruCache; } public LRUCache getCache(){ return cache; } public Person getPersonById(int id){ Person p; if ((p = cache.getPersonById(id) )== null){ //模拟假设从数据库中根据id查出对应的人 p= new Person(id,"p"+id,18,1); cache.addToList(p); } return p; } }
运行:
public class Test { public static void main(String[] args){ PersonList personList = new PersonList(new LRUCache(3)); Person p1 = personList.getPersonById(1); personList.getCache().iterator(); System.out.println("-------------------"); Person p2 = personList.getPersonById(2); personList.getCache().iterator(); System.out.println("-------------------"); Person p3 = personList.getPersonById(3); personList.getCache().iterator(); System.out.println("-------------------"); Person p5 = personList.getPersonById(2); personList.getCache().iterator(); System.out.println("-------------------"); Person p4 = personList.getPersonById(4); personList.getCache().iterator(); } 运行结果:1 p1-------------------2 p21 p1-------------------3 p32 p21 p1-------------------2 p23 p31 p1-------------------4 p42 p23 p3
LRU有好多种实现的方式,一般可以用双链表+hashtable,如果只用双链表的话,查找的时间复杂度为O(n),效率较慢
原文地址:https://www.cnblogs.com/zwb1/p/12180804.html
时间: 2024-10-11 18:00:13