1. 程式人生 > 資訊 >滴滴上線試行“司機收入報告”:乘客支付金額和司機收入金額一目瞭然

滴滴上線試行“司機收入報告”:乘客支付金額和司機收入金額一目瞭然

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();
    }
}