簡單的LRU Cache實現

class LRUCache {
    public static class Node {
        public int key;
        public int value;
        public Node pre;
        public Node next;

        public Node(int key, int value) {
            this.key = key;
            this.value = value;
        }
    }

    private int capacity;
    private Map<Integer, Node> cacheMap = new HashMap<>();
    private Node head;
    private Node tail;

    public LRUCache(int capacity) {
        this.capacity = capacity;
    }

    public int get(int key) {
        Node node = cacheMap.get(key);
        if (node != null) {
            moveNodeToTail(node);
            return node.value;
        }

        return -1;
    }

    public void put(int key, int value) {
        Node node = cacheMap.get(key);
        if (node != null) {
            node.value = value;
            moveNodeToTail(node);
            return;
        }

        Node newNode = new Node(key, value);
        cacheMap.put(key, newNode);
        appendNodeToTail(newNode);

        if (cacheMap.size() > capacity) {
            Node removed = removeHead();
            cacheMap.remove(removed.key);
        }
    }

    public void moveNodeToTail(Node node) {
        if (tail != node) {
            Node pre = node.pre;
            Node next = node.next;

            node.next = null;
            next.pre = pre;

            if (pre == null) {
                head = next;
            } else {
                pre.next = next;
            }

            node.pre = tail;
            tail.next = node;
            tail = node;
        }
    }

    public void appendNodeToTail(Node node) {
        Node last = tail;
        tail = node;

        if (last == null) {
            head = node;
        } else {
            last.next = node;
            node.pre = last;
        }
    }

    public Node removeHead() {
        Node removeNode = head;
        Node next = head.next;
        head.next = null;
        if (next != null) {
            next.pre = null;
        }
        head = next;
        return removeNode;
    }
}

或者可以用LinkedList代替自定義的雙向鏈表

private LinkedList<Node> deque = new LinkedList<>();

public void moveNodeToTail(Node node) {
	if (deque.getLast() != node) {
    	deque.remove(node);
        deque.addLast(node);
 	}
}

public void appendNodeToTail(Node node) {
	deque.addLast(node);
}

public Node removeHead() {
	return deque.removeFirst();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章