LRU緩存實(shí)踐

1.LRU是什么

Least Recently Used的縮寫(xiě),即最近最少使用

2.如何手寫(xiě)一個(gè)LRU

@使用雙鏈表
@使用map存儲(chǔ)元素
@為了方便操作,給雙鏈表添加偽頭節(jié)點(diǎn)和偽尾節(jié)點(diǎn)

3.實(shí)現(xiàn)說(shuō)明

1.為什么使用雙鏈表
雙鏈表添加、刪除元素只需修改前后指針,時(shí)間復(fù)雜度為O(1)
2.為什么使用map
map存取元素通過(guò)hash計(jì)算位置,時(shí)間復(fù)雜度也為O(1)

4.完成代碼如下

package com.shaw.kratos.common.cache;

import java.util.HashMap;
import java.util.Map;

/**
 * @author shaw
 * @date 2021/6/16
 */
public class LRUCache<K, V> extends AbstractCache<K, V> {

    private int cap;
    private int size = 0;
    private DLinkNode dummyHead;
    private DLinkNode dummyTail;

    private Map<K, DLinkNode<K, V>> map = new HashMap<>();

    public LRUCache(int cap) {
        this.cap = cap;
        this.dummyHead = new DLinkNode<>(-1, -1);
        this.dummyTail = new DLinkNode<>(-1, -1);
        dummyHead.next = dummyTail;
        dummyTail.prev = dummyHead;
    }

    @Override
    public void put(K key, V value) {
        if (size >= cap) {
            // 達(dá)到限制容量,刪除最少使用的元素,最少使用的元素在鏈表末尾
            DLinkNode needRemoveNode = dummyTail.prev;
            removeNode(needRemoveNode);
            map.remove(needRemoveNode.k);
            size--;
        }
        DLinkNode node = map.get(key);
        DLinkNode<K, V> addNode = new DLinkNode<>(key, value);
        if (null == node) {
            map.put(key, addNode);
            addHead(addNode);
            size++;
        } else {
            removeNode(node);
            addHead(addNode);
            map.put(key, addNode);
        }
    }

    @Override
    public V get(K key) {
        DLinkNode<K, V> node = map.get(key);
        if (null == node) {
            return null;
        }
        removeNode(node);
        addHead(node);
        return node.v;
    }

    private void addHead(DLinkNode node) {
        DLinkNode tmp = dummyHead.next;
        dummyHead.next = node;
        node.prev = dummyHead;
        node.next = tmp;
        tmp.prev = node;
    }

    private void removeNode(DLinkNode node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    private static class DLinkNode<K, V> {
        K k;
        V v;
        DLinkNode prev;
        DLinkNode next;
        DLinkNode(K k, V v) {
            this.k = k;
            this.v = v;
        }
    }
}

?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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