LeetCode LRU算法

LRU(Least recently used,最近最少使用)算法是目前廣泛使用的緩存淘汰算法。算法思想是如果數(shù)據(jù)最近被訪問(wèn)(讀或?qū)懀?,那么將?lái)被訪問(wèn)的概率也更高。所以長(zhǎng)期不被訪問(wèn)的數(shù)據(jù)將會(huì)被淘汰。

LeetCode的146題要求實(shí)現(xiàn)這一算法。

public class LRUCache {
    private final int capacity;
    private Map<Integer, Integer> map;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.map = new LinkedHashMap<Integer, Integer>() {
            private static final long serialVersionUID = 23L;

            @Override
            protected boolean removeEldestEntry(java.util.Map.Entry<Integer, Integer> eldest) {
                return size() > LRUCache.this.capacity;
            }
        };

    }

    public int get(int key) {
        Integer value = map.get(key);
        if (value != null) {
            map.remove(key);
            map.put(key, value);
        } else {
            value = -1;
        }
        return value;
    }

    public void put(int key, int value) {
        if (map.containsKey(key)) {
            map.remove(key);
        }
        map.put(key, value);
    }
}

上面這段代碼可以繼續(xù)優(yōu)化。

public LRUCache(int capacity) {
    this.capacity = capacity;
    this.map = new LinkedHashMap<Integer, Integer>(32, 0.75f, true) {
        private static final long serialVersionUID = 23L;

        @Override
        protected boolean removeEldestEntry(java.util.Map.Entry<Integer, Integer> eldest) {
            return size() > LRUCache.this.capacity;
        }
    };
}

LinkedHashMap本就可以按照訪問(wèn)訪問(wèn)順序排序,當(dāng)時(shí)沒(méi)有注意到這個(gè)構(gòu)造方法。其余代碼略去。

從LinkedHashMap的構(gòu)造方法來(lái)看,可以分成兩類:按插入順序排序,按訪問(wèn)順序排序。

我的提交代碼非常依賴LinkedHashMap這種數(shù)據(jù)結(jié)構(gòu),從類名上看來(lái),它和HashMap必然有所關(guān)系。其實(shí)它是HashMap的子類,在HashMap基礎(chǔ)上增加排序功能,讓輸出順序與插入順序或者訪問(wèn)順序相同,即最后一個(gè)插入(或訪問(wèn))的元素最后一個(gè)輸出。

HashMap的實(shí)現(xiàn)依賴鏈表數(shù)組(數(shù)組的每個(gè)元素是鏈表),但里面的元素是無(wú)序的。LinkedHashMap在其基礎(chǔ)之上,增加了一個(gè)鏈表來(lái)記錄元素的順序。

通過(guò)對(duì)比這兩類,完美體現(xiàn)了面向?qū)ο缶幊痰睦^承機(jī)制,需要深刻體會(huì)!

學(xué)習(xí)一個(gè)類的最基本最重要的方法就是JDK文檔。一段官方文檔,勝過(guò)千句啰嗦。

Hash table and linked list implementation of the Map interface, with predictable iteration order. This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries.

LinkedHashMap還可以在某種特點(diǎn)條件下removeEldestEntry,這也是實(shí)現(xiàn)LRU算法的一個(gè)關(guān)鍵。

Returns true if this map should remove its eldest entry. This method is invoked by put and putAll after inserting a new entry into the map. It provides the implementor with the opportunity to remove the eldest entry each time a new one is added. This is useful if the map represents a cache: it allows the map to reduce memory consumption by deleting stale entries.

常見(jiàn)用法:

private static final int MAX_ENTRIES = 100;
protected boolean removeEldestEntry(Map.Entry eldest) {
        return size() > MAX_ENTRIES;
}

原題:LRU Cache

參考資料:LinkedHashMap (Java Platform SE 8 )

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容