Java实现一个基于LRU时间复杂度为O(1)的缓存的方法

  介绍

这篇文章主要讲解了Java实现一个基于LRU时间复杂度为O(1)的缓存的方法,内容清晰明了,对此有兴趣的小伙伴可以学习一下,相信大家阅读完之后会有帮助。

LRU:最近最少使用最近最少使用,当缓存容量不足时,先淘汰最近最少使用的数据。就像JVM垃圾回收一样,希望将存活的对象移动到内存的一端,然后清除其余空间。

缓存基本操作就是读,写,淘汰删除。

读操作时间复杂度为O(1)的那就是散列操作了,可以使用HashMap索引关键。

写操作时间复杂度为O(1),使用链表结构,在链表的一端插入节点,是可以完成O(1)操作,但是为了配合读,还要再次将节点放入HashMap中,把操作最优是O(1),最差是O (n)。

不少童鞋就有疑问了,写入时又使用地图进行了把操作,为何缓存不直接使用地图吗?没错,首先使用地图存储了节点数据就是采用空间换时间,但是淘汰删除不好处理,使用地图如何去记录最近最少使用(涉及到时间,频次问题)所以,使用链表可以将活跃节点移动到链表的一端,淘汰时直接从另一端进行删除。

公共类LruCache{/* *这里简单点直接初始化了*/私人int能力=2;
  私人int大?0;
  DoubleListNode<私人HashMap比;缓存=new HashMap<祝辞(能力);
  私人DoubleListNodelruNode=new DoubleListNode(空,空,空,空);
  私人DoubleListNodemruNode=new DoubleListNode(空,空,空,空);
  
  公共V (K键){
  DoubleListNode目标=cache.get(关键);
  如果目标==null) {
  返回null;
  }/* *使用过就移动到右侧*/move2mru(目标);
  返回target.value;
  }
  
  公共空间把(K键,V值){
  如果(cache.containsKey(关键)){
  DoubleListNodetemp=cache.get(关键);
  temp.value=https://www.yisu.com/zixun/value;/* *使用过就移动到右侧*/move2mru(临时);
  返回;
  }/* *容量满了清除左侧*/如果(大?=能力){
  evict4lru ();
  }
  DoubleListNode  newNode=new DoubleListNode <> (mruNode、零键,值);
  如果(大?=0){
  lruNode。下一个=newNode;
  }
  mruNode。下一个=newNode;
  mruNode=newNode;
  cache.put(关键,newNode);
  大小+ +;
  }
  
  私人空间move2mru (DoubleListNode  newMru) {
  DoubleListNode  pre=newMru.pre;
  未来=newMru.next DoubleListNode ;
  精准医疗下一个=下一个;
  newMru。pre=mruNode;
  mruNode。下一个=newMru;
  mruNode=newMru;
  }
  
  私人空间evict4lru () {
  cache.remove (lruNode.next.key);
  lruNode。下一个=lruNode.next.next;
  大小,;
  }
  
  公共字符串toString () {
  StringBuffer某人=new StringBuffer (“lru ->”);
  DoubleListNode  temp=lruNode;
  而(临时!=null) {
  sb.append (temp.key) .append (“:”) .append (temp.value);
  sb.append (" -> ");
  temp=temp.next;
  }
  sb.append(“->系统”);
  返回sb.toString ();
  }
  
  公共静态void main (String [] args) {
  缓存=new LruCache LruCache <字符串,字符串> <> ();
  cache.put (“1”,“1”);
  System.out.println(缓存);
  cache.get (" 1 ");
  cache.put (“2”,“2”);
  System.out.println(缓存);
  cache.put (“3”,“3”);
  System.out.println(缓存);
  cache.put (“4”,“4”);
  System.out.println(缓存);
  }
  }
  
  类DoubleListNode  {
  K键;
  V值;
  DoubleListNode 前;
  DoubleListNode 下;
  
  公共DoubleListNode (K键,V值){
  这一点。键=键;
  这一点。值=价值;
  }
  
  公共DoubleListNode (DoubleListNode 之前,DoubleListNode 其次,K键,V值){
  这一点。pre=前;
  这一点。下一个=下一个;
  这一点。键=键;
  这一点。值=价值;
  }
  }

这里使用链表,及HashMap完成了基于LRU的缓存,其中HashMap主要用来快速索引键,链表用来完成LRU机制。当然尚有许多不足,包括缓存移除删除缓存ttl、线程安全等。

看完上述内容,是不是对Java实现一个基于LRU时间复杂度为O(1)的缓存的方法有进一步的了解,如果还想学习更多内容,欢迎关注行业资讯频道。

Java实现一个基于LRU时间复杂度为O(1)的缓存的方法