滴滴上線試行“司機收入報告”:乘客支付金額和司機收入金額一目瞭然
阿新 • • 發佈:2021-08-16
LRU是Least Recently Used 的縮寫,翻譯過來就是“最近最少使用”,LRU快取就是使用這種原理實現,簡單的說就是快取一定量的資料,當超過設定的閾值時就把一些過期的資料刪除掉,比如我們快取10000條資料,當資料小於10000時可以隨意新增,當超過10000時就需要把新的資料新增進來,同時要把過期資料刪除,以確保我們最大快取10000條,那怎麼確定刪除哪條過期資料呢,採用LRU演算法實現的話就是將最老的資料刪掉,廢話不多說,下面來說下Java版的LRU快取實現
Java裡面實現LRU快取通常有兩種選擇,一種是使用LinkedHashMap,一種是自己設計資料結構,使用連結串列+HashMap
LRU Cache的LinkedHashMap實現
LinkedHashMap自身已經實現了順序儲存,預設情況下是按照元素的新增順序儲存,也可以啟用按照訪問順序儲存,即最近讀取的資料放在最前面,最早讀取的資料放在最後面,然後它還有一個判斷是否刪除最老資料的方法,預設是返回false,即不刪除資料,我們使用LinkedHashMap實現LRU快取的方法就是對LinkedHashMap實現簡單的擴充套件,擴充套件方式有兩種,一種是inheritance,一種是delegation,具體使用什麼方式看個人喜好
//LinkedHashMap的一個建構函式,當引數accessOrder為true時,即會按照訪問順序排序,最近訪問的放在最前,最早訪問的放在後面 public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) { super(initialCapacity, loadFactor); this.accessOrder = accessOrder; } //LinkedHashMap自帶的判斷是否刪除最老的元素方法,預設返回false,即不刪除老資料 //我們要做的就是重寫這個方法,當滿足一定條件時刪除老資料 protected boolean removeEldestEntry(Map.Entry<K,V> eldest) { return false; }
LRU快取LinkedHashMap(inheritance)實現
採用inheritance方式實現比較簡單,而且實現了Map介面,在多執行緒環境使用時可以使用Collections.synchronizedMap()方法實現執行緒安全操作
package cn.lzrabbit.structure.lru; import java.util.LinkedHashMap; import java.util.Map; /** * Created by liuzhao on 14-5-15. */ public class LRUCache2<K, V> extends LinkedHashMap<K, V> { private final int MAX_CACHE_SIZE; public LRUCache2(int cacheSize) { super((int) Math.ceil(cacheSize / 0.75) + 1, 0.75f, true); MAX_CACHE_SIZE = cacheSize; } @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > MAX_CACHE_SIZE; } @Override public String toString() { StringBuilder sb = new StringBuilder(); for (Map.Entry<K, V> entry : entrySet()) { sb.append(String.format("%s:%s ", entry.getKey(), entry.getValue())); } return sb.toString(); } }