Java實現一個簡單的LRU緩存對象

LRU(Least Recently Used)算法的核心思想是:最近使用的數據將被保留,最久未使用的數據將被淘汰。這種策略適用于內存有限、但又需要高頻訪問的數據場景,比如緩存系統、頁面置換算法等。

mysql的緩沖池就是使用的LUR

InnoDB緩沖池通過雙向鏈表和哈希表實現LRU機制:

  • 雙向鏈表按訪問時間排序,最新訪問的緩存頁在頭部,最久未使用的在尾部

  • 哈希表用于快速定位鏈表節點

代碼實現

import java.util.HashMap;public class LRUCache<K, V> {// 鏈表節點對象private class Node {K key;V value;// 定義上下節點, prev=上一個節點, next=下一個節點Node prev, next;public Node(K key, V value) {this.key = key;this.value = value;}}private final int capacity;private final HashMap<K, Node> cache;// 定義頭部節點和尾部節點, 這兩個節點都不存儲數據, 只做頭尾指向使用private Node head, tail;public LRUCache(int capacity) {this.capacity = capacity;this.cache = new HashMap<>((int) ((capacity / 0.75) + 1));this.head = new Node(null, null);this.tail = new Node(null, null);this.head.next = this.tail;this.tail.prev = this.head;}public V get(K key) {Node node = this.cache.get(key);if (node == null) {return null;}// 將當前節點移動到頭部節點this.moveToHead(node);return node.value;}public void put(K key, V value) {Node node = this.cache.get(key);if (node == null) {Node newNode = new Node(key, value);// 添加到頭部節點, 新節點一定要使用添加, 不能使用移動, 因為新節點的上下節點指向還未賦值this.addToHead(newNode);this.cache.put(key, newNode);if (this.cache.size() > capacity) {// 移除尾部節點Node tailNode = this.removeTail();this.cache.remove(tailNode.key);}} else {node.value = value;// 移動到頭部節點this.moveToHead(node);}}// 移動當前節點到頭部節點private void moveToHead(Node node) {// 先移除當前節點, 保證原來鏈表的上下完整性this.removeNode(node);// 將當前節點添加到頭部節點this.addToHead(node);}// 添加頭部節點private void addToHead(Node node) {// 假設原來的鏈表結構: head <-> A, null <-> B <-> null, 其中B是當前節點// 現在的鏈表結構: head <-> B <-> A// 第一步, 修改B的上一個指向和下一個指向// 第二步, 修改head的下一個指向, 修改A的上一個指向node.prev = this.head;node.next = this.head.next;this.head.next.prev = node;this.head.next = node;}// 移除當前節點private void removeNode(Node node) {// 將[當前節點]的[上一個節點]的[下一個節點]指向[當前節點]的[下一個節點]// 將[當前節點]的[下一個節點]的[上一個節點]指向[當前節點]的[上一個節點]// 假設原來的鏈表結構: A <-> B <-> C, 其中B是當前節點// 原來的鏈表結構: A <-> B <-> C// 現在的鏈表結構: A <-> C, 這里做了兩步, 修改A的下一個指向, 修改C的上一個指向node.prev.next = node.next;node.next.prev = node.prev;}// 移除尾部節點private Node removeTail() {// 獲取最后一個節點Node node = this.tail.prev;// 移除當前節點this.removeNode(node);return node;}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/94325.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/94325.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/94325.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

整體設計 之定稿 “凝聚式中心點”原型 --整除:智能合約和DBMS的在表層掛接 能/所 依據的深層套接 之2

摘要三“式”三“心”三“物” 整數原型三段式表達 的 凝聚式中心點dot 、組織式核心元素位element和分析式內核基因座locus 三者分別以**“等號線&#xff08;Arc&#xff09;”**&#xff08;動態關聯&#xff09;、**“邊界線&#xff08;Transition&#xff09;”**&#…

vue.根據url生成二維碼

文章目錄概要QR碼步驟1. 引入庫2. 生成二維碼3. 將二維碼加入頁面中用javascript庫簡化二維碼生成1. 引入庫2. 使用庫生成二維碼二維碼美化和定制1. 調整大小2. 調整顏色3. 添加自定義形狀和圖案4. 添加logo性能優化與錯誤處理1. 減少不必要的計算2. 異步處理概要 生成 URL 二…

WPF+MVVM入門學習

最近在學WPF的MVVM&#xff0c;有兩種方式實現&#xff0c;一種是自己實現&#xff0c;一種是借助MVVM框架&#xff0c;接下來通過一個醫院自助打印報告機鍵盤輸入界面來演示自己實現、框架CommunityToolkit和Prism的區別。 項目源碼&#xff1a;https://gitee.com/cplmlm/Sel…

[e3nn] docs | 不可約表示(Irreps)

鏈接&#xff1a;https://docs.e3nn.org/en/latest/examples/examples.html docs&#xff1a;e3nn e3nn是一個用于構建歐幾里得(E(3))等變神經網絡的Python庫&#xff0c;這意味著它們能自動保持三維旋轉和反射的對稱性。 該庫使用不可約表示(Irreps)來描述數據變換方式&…

深入淺出 ArrayList:從基礎用法到底層原理的全面解析(中)

四、ArrayList 常用方法實戰 —— 從添加到遍歷的全場景覆蓋ArrayList 提供了數十個方法&#xff0c;但日常開發中常用的只有 10 個左右&#xff0c;我們按 “元素操作”“集合查詢”“遍歷方式” 三類來梳理&#xff0c;每個方法都附帶示例和注意事項。4.1 元素添加&#xff1…

java后端如何實現下載功能

后端需要把要下載的若干文件 按 ZIP 格式編碼成一段二進制字節流&#xff0c;然后以 Content-Type: application/zip Content-Disposition: attachment; filenamexxx.zip 的形式寫進 HTTP 響應體。瀏覽器收到這段“ZIP 格式的字節流”后&#xff0c;就會彈出保存對話框&#xf…

AI生成技術報告:GaussDB與openGauss的HTAP功能全面對比

GaussDB 與 openGauss 的 HTAP 功能比較 前言 GaussDB集中式版本從505.2版本開始引入了HTAP混合負載功能&#xff0c;openGauss也從7.0.0 RC1版本開始引入了HTAP行列融合功能&#xff0c;加強了行存轉列存的使用友好度&#xff0c;但兩者的實現似乎存在不小的差異。 雖然文檔…

小程序開發指南(四)(UI 框架整合)

?講解了微信小程序 UI 框架的使用方法和特點&#xff0c;根據項目需求選擇合適的組件庫。附有相應的組件庫預覽碼&#xff0c;也是將所有的微信小程序原生組件庫整合在一起方便后續開發的使用。如果有不好或者有錯誤的地方請告知&#xff01;希望可以與大家相互的交流學習&…

golang 1.25.0 安裝

wget https://golang.google.cn/dl/go1.25.0.linux-amd64.tar.gz tar -C /usr/local/ -xzf go1.25.0.linux-amd64.tar.gz ln -s /usr/local/go/bin/* /usr/bin/ go env -w GO111MODULEon go env -w GOPROXYhttps://goproxy.cn,direct

基于深度學習的人臉表情識別系統:YOLOv5/v6/v7/v8/v10模型實現與UI界面集成

基于YOLOv5/v7/v8的智能人臉表情識別系統:從算法原理到應用實現 表情識別的技術價值與挑戰 人臉表情識別(Facial Expression Recognition, FERYOLOv5/v7/v8等深度學習算法構建高效的表情識別系統,并設計直觀的UI界面集成方案。無論你是深度學習初學者還是有經驗的開發者,…

初步了解多線程

系列文章目錄 目錄 系列文章目錄 前言 一、進程 二、線程 1. 線程解決資源開銷的方式 2. 線程和進程的聯系和區別 三、多線程編程 1. 直觀了解多線程 2. 線程的創建方式 1. 繼承 Thread 重寫 run() 方法 2. 實現 Runable 接口&#xff0c;重寫 run() 方法 3. 繼承 …

安卓Android低功耗藍牙BLE連接異常報錯133

安卓Android低功耗藍牙BLE連接異常報錯133 之前連接一直好好的,不知道為什么今天突然就連接不了藍牙了,報錯133,按照 找網上的說明總是說清除GATT緩存,其實并不是我的問題,最后看到這里https://softs.im/android-ble-%e8%bf%9e%e6%8e%a5%e9%94%99%e8%af%af133/ 有如下說明: 情…

【分治】快排與歸并專題

分治思想 分&#xff08;Divide&#xff09;&#xff1a;將待排序數組不斷拆分為兩個等長&#xff08;或近似等長&#xff09;的子數組&#xff0c;直到子數組長度為 1&#xff08;天然有序&#xff09;。 治&#xff08;Conquer&#xff09;&#xff1a;遞歸排序每個子數組。 …

[Linux]學習筆記系列 -- mm/page_alloc

文章目錄mm/page_alloc.c 伙伴系統內存分配器(Buddy System Memory Allocator) 內核物理內存管理的核心歷史與背景這項技術是為了解決什么特定問題而誕生的&#xff1f;它的發展經歷了哪些重要的里程碑或版本迭代&#xff1f;目前該技術的社區活躍度和主流應用情況如何&#xf…

3秒傳輸大文件:cpolar+Localsend實現跨網絡秒傳

文章目錄前言1. 在Windows上安裝LocalSend2. 安裝Cpolar內網穿透3. 公網訪問LocalSend4. 固定LocalSend公網地址用 cpolar 讓 Localsend 突破距離限制就是這么簡單&#xff01;三步輕松搞定&#xff1a;在手機和電腦上都安裝 Localsend&#xff0c;在其中一臺設備上運行 cpolar…

基于STM32單片機智能RFID刷卡汽車位鎖樁設計

1 系統功能介紹 本系統是一個 基于 STM32 單片機的智能 RFID 刷卡車位鎖樁控制系統&#xff0c;其設計理念來源于現實中智能停車場的車位鎖樁管理。通過 RFID 刷卡認證、LCD1602 顯示、繼電器控制以及按鍵輔助操作&#xff0c;實現對車位的安全管理。該系統不僅模擬了車輛駛入與…

SQL185 試卷完成數同比2020年的增長率及排名變化

描述現有試卷信息表examination_info&#xff08;exam_id試卷ID, tag試卷類別, difficulty試卷難度, duration考試時長, release_time發布時間&#xff09;&#xff1a;試卷作答記錄表exam_record&#xff08;uid用戶ID, exam_id試卷ID, start_time開始作答時間, submit_time交…

網絡編程中的TCP——TCP的連接的建立、關閉、狀態轉移

網絡編程中的TCP——TCP的連接的建立、關閉、狀態轉移 TCP連接的建立和關閉wireshark捕獲數據&#xff1a;TCP三次握手四次揮手的時序圖&#xff1a;三次握手&#xff1a; 報文段1包含SYN標志&#xff0c;這是一個同步報文段&#xff0c;表示發起連接請求&#xff0c;包含自己起…

SQL 語句拼接在 C 語言中的實現與安全性分析

代碼解析 // 構建SQL插入語句 char *sql_insert (char *)malloc(sizeof(char) * 200); // 分配200字節內存 strcpy(sql_insert, "INSERT INTO user(username, passwd) VALUES("); // 復制基礎SQL語句 strcat(sql_insert, ""); // 添加單引號 strcat(sq…