国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

淺談Java如何實(shí)現(xiàn)一個(gè)基于LRU時(shí)間復(fù)雜度為O(1)的緩存

瀏覽:3日期:2022-08-27 15:14:09

LRU:Least Recently Used最近最少使用,當(dāng)緩存容量不足時(shí),先淘汰最近最少使用的數(shù)據(jù)。就像JVM垃圾回收一樣,希望將存活的對(duì)象移動(dòng)到內(nèi)存的一端,然后清除其余空間。

緩存基本操作就是讀、寫(xiě)、淘汰刪除。

讀操作時(shí)間復(fù)雜度為O(1)的那就是hash操作了,可以使用HashMap索引 key。

寫(xiě)操作時(shí)間復(fù)雜度為O(1),使用鏈表結(jié)構(gòu),在鏈表的一端插入節(jié)點(diǎn),是可以完成O(1)操作,但是為了配合讀,還要再次將節(jié)點(diǎn)放入HashMap中,put操作最優(yōu)是O(1),最差是O(n)。

不少童鞋就有疑問(wèn)了,寫(xiě)入時(shí)又使用map進(jìn)行了put操作,為何緩存不直接使用map?沒(méi)錯(cuò),首先使用map存儲(chǔ)了節(jié)點(diǎn)數(shù)據(jù)就是采用空間換時(shí)間,但是淘汰刪除不好處理,使用map如何去記錄最近最少使用(涉及到時(shí)間、頻次問(wèn)題)。so,使用鏈表可以將活躍節(jié)點(diǎn)移動(dòng)到鏈表的一端,淘汰時(shí)直接從另一端進(jìn)行刪除。

public class LruCache<K,V> {/** 這里簡(jiǎn)單點(diǎn)直接初始化了*/ private int capacity = 2; private int size = 0; private HashMap<K,DoubleListNode<K,V>> cache = new HashMap<>(capacity); private DoubleListNode<K,V> lruNode = new DoubleListNode<K, V>(null,null,null,null); private DoubleListNode<K,V> mruNode = new DoubleListNode<K, V>(null,null,null,null); public V get(K key){ DoubleListNode<K,V> target = cache.get(key); if (target == null) { return null; } /** 使用過(guò)就移動(dòng)到右側(cè) */ move2mru(target); return target.value; } public void put(K key,V value){ if(cache.containsKey(key)){ DoubleListNode<K,V> temp = cache.get(key); temp.value = value; /** 使用過(guò)就移動(dòng)到右側(cè) */ move2mru(temp); return; }/** 容量滿了清除左側(cè) */ if(size >= capacity){ evict4lru(); } DoubleListNode<K,V> newNode = new DoubleListNode<>(mruNode,null,key,value); if(size == 0){ lruNode.next = newNode; } mruNode.next = newNode; mruNode = newNode; cache.put(key,newNode); size++; } private void move2mru(DoubleListNode<K,V> newMru){ DoubleListNode<K,V> pre = newMru.pre; DoubleListNode<K,V> next = newMru.next; pre.next = next; newMru.pre = mruNode; mruNode.next = newMru; mruNode = newMru; } private void evict4lru(){ cache.remove(lruNode.next.key); lruNode.next = lruNode.next.next; size--; } public String toString(){ StringBuffer sb = new StringBuffer('lru -> '); DoubleListNode<K,V> temp = lruNode; while(temp!=null){ sb.append(temp.key).append(':').append(temp.value); sb.append(' -> '); temp = temp.next; } sb.append(' -> mru '); return sb.toString(); } public static void main(String[] args) { LruCache<String,String> cache = new LruCache<>(); cache.put('1','1'); System.out.println(cache); cache.get('1'); cache.put('2','2'); System.out.println(cache); cache.put('3','3'); System.out.println(cache); cache.put('4','4'); System.out.println(cache); }}class DoubleListNode<K,V>{ K key; V value; DoubleListNode<K,V> pre; DoubleListNode<K,V> next; public DoubleListNode(K key,V value){ this.key = key; this.value = value; } public DoubleListNode(DoubleListNode<K,V> pre,DoubleListNode<K,V> next,K key,V value){ this.pre = pre; this.next = next; this.key = key; this.value = value; }}

這里使用鏈表,及HashMap完成了基于LRU的緩存,其中HashMap主要用來(lái)快速索引key,鏈表用來(lái)完成LRU機(jī)制。當(dāng)然尚有許多不足,包括緩存移除remove,緩存ttl,線程安全等。

到此這篇關(guān)于淺談Java如何實(shí)現(xiàn)一個(gè)基于LRU時(shí)間復(fù)雜度為O(1)的緩存的文章就介紹到這了,更多相關(guān)Java基于LRU時(shí)間復(fù)雜度為O(1)的緩存內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 欧美亚洲国产人成aaa | 777色狠狠一区二区三区 | 久久综合日韩亚洲精品色 | 一级特级aaa毛片 | 深夜在线观看大尺度 | 国产精品偷伦费观看 | 久久久香蕉视频 | 国产精品久久久一区二区三区 | 亚洲国产精品成人综合久久久 | 日韩在线观看一区二区三区 | 亚洲黄色第一页 | 日韩国产精品99久久久久久 | 精品欧美小视频在线观看 | 中文字幕最新中文字幕中文字幕 | 免费看美女无遮掩的软件 | 免费在线观看一区二区 | 国产日产韩产麻豆1区 | 韩国福利影视一区二区三区 | 国产精品尹人在线观看免费 | 久久精品国产一区二区三区 | 2022久久免费精品国产72精品 | 国产一区二区亚洲精品 | 欧美午夜视频在线 | a级国产精品片在线观看 | a毛片免费全部播放完整成 a毛片免费全部在线播放毛 | 国内国外精品一区二区 | 久久久精品成人免费看 | 刺激一区仑乱 | 特黄特黄aaaa级毛片免费看 | 日本高清在线中文字幕网 | 亚洲精品成人 | 特级做人爱c级特级aav毛片 | 日韩精品一区二区三区免费观看 | 欧美一区二区三区在线视频 | 香港经典a毛片免费观看看 香港经典a毛片免费观看爽爽影院 | 日本高清一本二本三本如色坊 | 日韩一级欧美一级毛片在线 | 免费国产一级特黄久久 | 中文字幕在线无限2021 | 亚洲欧美日韩久久一区 | 欧美日韩精品一区二区三区高清视频 |