全文目錄:
- 開篇語
- 前言
- 1. LinkedHashMap 簡介
- 1.1 LinkedHashMap 的構造方法
- 2. 基于 LinkedHashMap 實現 LRU 緩存
- 2.1 設計思路
- 2.2 實現步驟
- 2.3 代碼說明
- 2.4 測試案例
- 2.5 解釋
- 3. LRU 緩存優化
- 3.1 `removeEldestEntry()` 方法的靈活性
- 3.2 內存管理
- 4. 總結
- 文末
開篇語
哈嘍,各位小伙伴們,你們好呀,我是喵手。運營社區:C站/掘金/騰訊云/阿里云/華為云/51CTO;歡迎大家常來逛逛
??今天我要給大家分享一些自己日常學習到的一些知識點,并以文字的形式跟大家一起交流,互相學習,一個人雖可以走的更快,但一群人可以走的更遠。
??我是一名后端開發愛好者,工作日常接觸到最多的就是Java語言啦,所以我都盡量抽業余時間把自己所學到所會的,通過文章的形式進行輸出,希望以這種方式幫助到更多的初學者或者想入門的小伙伴們,同時也能對自己的技術進行沉淀,加以復盤,查缺補漏。
小伙伴們在批閱的過程中,如果覺得文章不錯,歡迎點贊、收藏、關注哦。三連即是對作者我寫作道路上最好的鼓勵與支持!
前言
在很多實際的應用中,尤其是需要緩存數據的場景下,我們經常會遇到 LRU(Least Recently Used,最近最少使用)緩存。LRU 緩存是通過淘汰最久未使用的緩存數據來節省內存空間。對于高效的 LRU 緩存,我們不僅要保證快速的查找、插入和刪除操作,還要能夠快速地淘汰最久未使用的元素。
在 Java 中,基于 LinkedHashMap
實現 LRU 緩存是非常簡便和高效的,因為 LinkedHashMap
本身提供了按照訪問順序迭代的能力,我們可以利用這一特性輕松實現 LRU 緩存。
1. LinkedHashMap 簡介
LinkedHashMap
是 HashMap
的一個子類,它基于哈希表實現,并且維護了插入順序或訪問順序。這使得 LinkedHashMap
特別適合于實現緩存,尤其是在需要按訪問順序迭代時。
1.1 LinkedHashMap 的構造方法
LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)
:initialCapacity
:初始容量。loadFactor
:負載因子。accessOrder
:如果設置為true
,則按照訪問順序排序;如果設置為false
,則按照插入順序排序。
當 accessOrder
設置為 true
時,LinkedHashMap
會在每次訪問(get 或 put 操作)時,將訪問的元素移動到鏈表的末尾。這個特性讓我們能夠輕松地實現 LRU 緩存。
2. 基于 LinkedHashMap 實現 LRU 緩存
2.1 設計思路
- 緩存大小限制:我們需要為緩存設定一個最大容量
capacity
,當緩存容量超過該值時,我們就需要淘汰最久未使用的元素。 - LRU 淘汰規則:在每次插入或訪問元素時,我們將該元素移動到鏈表的末尾,這樣鏈表的頭部始終保存著最久未使用的元素。當緩存容量超過限制時,我們可以直接刪除鏈表頭部的元素。
- 使用 LinkedHashMap:利用
LinkedHashMap
中accessOrder
的特性,結合removeEldestEntry()
方法來自動刪除最久未使用的元素。
2.2 實現步驟
我們可以創建一個繼承自 LinkedHashMap
的類,并重寫 removeEldestEntry()
方法,該方法會在每次插入新元素時被調用。
import java.util.LinkedHashMap;
import java.util.Map;public class LRUCache<K, V> extends LinkedHashMap<K, V> {private final int capacity;// 構造函數,初始化容量和 accessOrderpublic LRUCache(int capacity) {super(capacity, 0.75f, true); // 第三個參數 true 表示按訪問順序排序this.capacity = capacity;}// 重寫 removeEldestEntry 方法,當緩存容量超出時,移除最久未使用的條目@Overrideprotected boolean removeEldestEntry(Map.Entry<K, V> eldest) {return size() > capacity;}// 獲取緩存中的值public V get(K key) {return super.getOrDefault(key, null);}// 插入緩存值public void put(K key, V value) {super.put(key, value);}
}
2.3 代碼說明
LRUCache
類繼承自LinkedHashMap
,并通過構造函數設置了accessOrder
為true
,這使得每次訪問元素時,該元素都會被移到鏈表的末尾。removeEldestEntry()
方法會在每次插入新元素時檢查緩存的大小。如果緩存的大小超過了設定的容量,它會返回true
,從而自動移除最久未使用的元素。get(K key)
和put(K key, V value)
方法分別用于獲取和插入緩存中的數據。
2.4 測試案例
public class Main {public static void main(String[] args) {// 創建一個容量為 3 的 LRU 緩存LRUCache<Integer, String> cache = new LRUCache<>(3);// 向緩存中插入數據cache.put(1, "A");cache.put(2, "B");cache.put(3, "C");// 打印緩存內容System.out.println(cache); // 輸出: {1=A, 2=B, 3=C}// 訪問元素 1cache.get(1); // 使元素 1 最近訪問// 插入新的元素,此時緩存超過容量,元素 2 將被移除cache.put(4, "D");// 打印緩存內容System.out.println(cache); // 輸出: {3=C, 1=A, 4=D}}
}
輸出:
{1=A, 2=B, 3=C}
{3=C, 1=A, 4=D}
2.5 解釋
- 初始時,緩存的容量為 3,元素
{1=A, 2=B, 3=C}
被插入緩存。 - 當訪問
get(1)
時,元素 1 被移動到鏈表的末尾。 - 當插入元素
4=D
時,由于緩存已經滿了,元素 2(最久未訪問)被自動刪除,最終緩存內容為{3=C, 1=A, 4=D}
。
3. LRU 緩存優化
3.1 removeEldestEntry()
方法的靈活性
通過 removeEldestEntry()
方法,我們可以根據不同的需求定制緩存的淘汰規則。例如,我們可以根據某些條件(如元素的大小、元素的過期時間等)來決定是否刪除最久未使用的元素。
3.2 內存管理
雖然 LinkedHashMap
的 accessOrder
特性和 removeEldestEntry()
方法讓我們能夠很方便地實現 LRU 緩存,但也需要注意緩存大小和內存使用的平衡。特別是當緩存需要存儲大量數據時,合理設置緩存容量和定期清理緩存非常重要。
4. 總結
- 使用
LinkedHashMap
實現 LRU 緩存的方式簡潔高效,特別適合需要按訪問順序管理緩存數據的場景。 - 通過重寫
removeEldestEntry()
方法,我們能夠在緩存超出容量時自動移除最久未使用的元素。 - 這種方法不僅具有較高的性能,還能避免重復的復雜操作,方便開發者實現高效的緩存管理。
LRU 緩存的實現,幫助我們在高效處理數據時保持內存的合理使用,避免內存溢出或緩存過期問題的出現。
… …
文末
好啦,以上就是我這期的全部內容,如果有任何疑問,歡迎下方留言哦,咱們下期見。
… …
學習不分先后,知識不分多少;事無巨細,當以虛心求教;三人行,必有我師焉!!!
wished for you successed !!!
??若喜歡我,就請關注我叭。
??若對您有用,就請點贊叭。
??若有疑問,就請評論留言告訴我叭。
版權聲明:本文由作者原創,轉載請注明出處,謝謝支持!