java實現lru

網上說了很多linkhashmap的實現,但是我覺得還是不要用jdk的工具,自己用最原始的方式實現才更有利於理解。

public class Lru {
    private static final int MAX_NUM = 3;
    //用來記錄節點,使得遍歷鏈表複雜度降低到O(1)
    private static ConcurrentHashMap<String, Link.Entry> tmpMap = new ConcurrentHashMap<>(MAX_NUM);
    private static Link link = new Link();

    public static String get(String key) {
        Link.Entry entry = tmpMap.get(key);
        link.remove(entry);
        link.insertFirst(entry);

        return entry.value;
    }

    public static void put(String key, String value) {
        if (tmpMap.containsKey(key)) {
            link.remove(tmpMap.get(key));
            link.insertFirst(tmpMap.get(key));
            return;
        }

        if (tmpMap.size() >= MAX_NUM) {
            link.remove(link.tail.before);
        }

        Link.Entry entry = link.new Entry(null, null, key, value);
        link.insertFirst(entry);
        tmpMap.put(key, entry);
    }

    public static void main(String[] args) {
        Lru.put("1", "a");
        Lru.put("2", "b");
        Lru.put("3", "c");
        Lru.put("4", "d");
        Lru.put("2", "b");

        Link.Entry entry = link.head.after;
        while (entry.after != null) {
            System.out.println("key: " + entry.key + " value: " + entry.value);
            entry = entry.after;
        }
    }
}

//雙向鏈表
class Link {
    Entry head;
    Entry tail;

    public Link() {
        head = new Entry();
        tail = new Entry();
        head.setAfter(tail);
        tail.setBefore(head);
    }

    @Setter
    @Getter
    @NoArgsConstructor
    @AllArgsConstructor
    class Entry {
        Entry before;
        Entry after;
        String key;
        String value;
    }

    //此部分比較麻煩,由於是雙向鏈表所以,修改指針時候要注意前後節點都要修改
    public void insertFirst(Entry entry) {
        entry.after = head.after;
        entry.after.before = entry;
        entry.before = head;
        head.after = entry;
        if (tail.before == head) {
            tail.before = entry;
        }
    }

    public void remove(Entry entry) {
        entry.before.after = entry.after;
        entry.after.before = entry.before;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章