LRU缓存机制的实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LRU缓存机制的实现相关的知识,希望对你有一定的参考价值。
参考技术A leetcode 146.LRU(Least Recently Used)是一种缓存替换策略。现实生活中,缓存的大小总是有限的,为了合理地利用缓存,在缓存满了以后需要利用合适的替换策略把某些内容从缓存中移出,以腾出空间给新的元素。LRU就是其中一种常见的策略,它把缓存中最不常访问到的数据移出。
为了实现LRU,可以利用哈希表+双向链表。哈希表以键值对的形式保存元素,并以O(1)的时间复杂度取出元素;双向链表用于记录每个元素的使用情况。具体如下:
参考:
[1] https://zhuanlan.zhihu.com/p/76553221
java 自定义 LRU(最近最少使用)策略 实现 缓存机制
1. java提供了一个简单的方式实现LRU: LinkedHashMap
2. 自定义实现
LRU至少需要两个主要操作: 添加(add)和搜索(search)
public class LRUCache { private Map<String, CacheEntry> map; private CacheEntry head , tail; private int maxSize; public LRUCache(int maxSize){ if(maxSize < 1){ throw new IllegalArgumentException("Cache maxSize has to be at least 1"); } this.map = new HashMap<String, CacheEntry>(); head = new CacheEntry("head",""); tail = new CacheEntry("tail", ""); head.setNext(tail); tail.setPrev(head); this.maxSize = maxSize; } public void add(String key, String value){ CacheEntry cacheEntry = map.get(key); if(cacheEntry == null){ cacheEntry = new CacheEntry(key, value); if(map.size() == maxSize){ //缓存达到最大数目 //删除最老的条目 CacheEntry deleteEntry = tail.getPrev(); //从map中移除 map.remove(deleteEntry.getKey()); //从队列中移除 remove(deleteEntry); } //添加条目到队列 addFront(cacheEntry); //添加到map map.put(key, cacheEntry); }else{ //更新值 cacheEntry.setValue(value); //访问条目 accessed(cacheEntry); } } public String search(String key){ CacheEntry entry = map.get(key); if(entry == null){ return null; } accessed(entry); return entry.getValue(); } //打印缓存内容 public void print(){ CacheEntry entry = head.getNext(); while(entry != tail){ System.out.println("{" + entry.getKey() + ":" + entry.getValue() + "}"); entry = entry.getNext(); } System.out.println(); } public void accessed(CacheEntry entry) { if(entry.getPrev() != head){ remove(entry); addFront(entry); } } private void addFront(CacheEntry entry) { //在队列的头部添加条目 CacheEntry nextEntry = head.getNext(); head.setNext(entry); entry.setPrev(head); entry.setNext(nextEntry); if(nextEntry != null){ nextEntry.setPrev(entry); } } private void remove(CacheEntry entry) { if(entry == head || entry == tail){ return;//错误 } entry.getPrev().setNext(entry.getNext()); if(entry.getNext() != null){ entry.getNext().setPrev(entry.getPrev()); } } } /** * Created by admin on 2018/3/30. */ public class CacheEntry { private CacheEntry prev, next; private String key, value; CacheEntry(String key, String value){ this.key = key; this.value = value; } public CacheEntry getPrev() { return prev; } public void setPrev(CacheEntry prev) { this.prev = prev; } public CacheEntry getNext() { return next; } public void setNext(CacheEntry next) { this.next = next; } public String getKey() { return key; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
以上是关于LRU缓存机制的实现的主要内容,如果未能解决你的问题,请参考以下文章