日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HashMap实现LRU(最近最少使用)缓存更新算法

發布時間:2023/12/4 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HashMap实现LRU(最近最少使用)缓存更新算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近阿里巴巴電話面試被問到了如何使用固定容量的HashMap,實現LRU算法。當時一臉懵逼,平時用HashMap也就用來快速存取數據而已,容量都是不限的。

想了半天,想到對node節點進行擴展,加入引用計數,然后到達指定容量后,刪除引用計數最少的。
面試官質疑這樣效率太低了,能不能優化下。
想到刪除時,需要遍歷所有元素,代價為O(n),太大了。想到可以用最小堆來進行篩選。被問到建堆的節點值是什么,這塊沒想好,卡殼了。

面試完之后,網上搜了下,才發現Java官方已經替我們預留了LRU算法的框架,在LinkedHashMap里。我們只需要擴展下即可,代碼示例如下:

/*** Constructs an empty <tt>LinkedHashMap</tt> instance with the* specified initial capacity, load factor and ordering mode.** @param initialCapacity the initial capacity* @param loadFactor the load factor* @param accessOrder the ordering mode - <tt>true</tt> for* access-order, <tt>false</tt> for insertion-order* @throws IllegalArgumentException if the initial capacity is negative* or the load factor is nonpositive*/public LinkedHashMap(int initialCapacity,float loadFactor,boolean accessOrder) {super(initialCapacity, loadFactor);this.accessOrder = accessOrder;}//方法為protected ,擺明了是想被繼承、重寫protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {return false;}

使用accessOrder來標識是使用訪問順序,還是插入順序。默認為插入順序。當accessOrder為訪問順序、容量固定時,即為LRU
舉例如下:

class LRULinkedHashMap<K,V> extends LinkedHashMap<K,V> {/*** */private static final long serialVersionUID = 1882839504956564761L;private int capacity;public LRULinkedHashMap(int capacity) {super(capacity,0.75f,true);this.capacity = capacity;}@Overridepublic boolean removeEldestEntry(Map.Entry<K,V> eldest) {System.out.println("即將根據LRU算法,刪除最近最少使用元素:key= "+eldest.getKey()+" value= "+eldest.getValue()+" .");//此行代碼是關鍵,一旦容量超出限制,即按照LRU進行刪除return size()>capacity;} } public class Test {public static void main(String[] args) {testLinkedHashMap();testLRULinkedHashMap();}public static void testLinkedHashMap() {//容量固定,accessOrder=trueMap<Integer, Integer> map = new LinkedHashMap<Integer, Integer>(5, 0.75f, true);map.put(1, 1);map.put(2, 2);map.put(3, 3);map.put(4, 4);map.put(5, 5);//此時輸出1,2,3,4,5for(Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator(); it.hasNext();) {System.out.println(it.next().getValue());}map.put(4, 4);map.put(6, 6);//此時輸出1,2,3,5,4,6(自動擴容)for(Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator(); it.hasNext();) {System.out.println(it.next().getValue());}}public static void testLRULinkedHashMap() {//容量固定,accessOrder=trueMap<Integer, Integer> map = new LRULinkedHashMap<Integer, Integer>(5);map.put(1, 1);map.put(2, 2);map.put(3, 3);map.put(4, 4);map.put(5, 5);//此時輸出1,2,3,4,5for(Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator(); it.hasNext();) {System.out.println(it.next().getValue());}map.put(4, 4);map.put(6, 6);//此時輸出2,3,5,4,6(容量鎖定,進行刪除)for(Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator(); it.hasNext();) {System.out.println(it.next().getValue());}}}

總結

以上是生活随笔為你收集整理的HashMap实现LRU(最近最少使用)缓存更新算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。