官方解法:创建一个双向链表,实现这个功能。用一个hashMap来进行映射,判断链表中是否有某个key,并O(1)找到这个node
/**
* 当缓存容量达到上限时,
* 它应该在写入新数据之前删除最久未使用的数据值,
* 从而为新的数据值留出空间。
*/
// 用一个双向链表来解题。用hashMap来查找是否有键值对。
class LRUCache {
public static void main(String[] args) {
LRUCache lruCache = new LRUCache(1);
lruCache.put(2, 1);
int i = lruCache.get(2);
System.out.println(i);//1
lruCache.put(3, 2);
int i1 = lruCache.get(2);
System.out.println(i1);//-1
}
class Node {
Node pre;
Node next;
int key;
int value;
Node(int key, int value) {
this.key = key;
this.value = value;
}
Node() {
}
}
HashMap<Integer, Node> map;
int size;
Node head;
Node tail;
int capacity;
public LRUCache(int capacity) {
map = new HashMap<>();
size = 0;
head = new Node();
tail = new Node();
head.next = tail;
tail.pre = head;
this.capacity = capacity;
}
public int get(int key) {
Node node = map.get(key);
if (node == null) return -1;
else { // 有这个key
moveToFirst(node);
return node.value;
}
}
public void put(int key, int value) {
Node node = map.get(key);
if (node == null) { // 进行插入。
Node newNode = new Node(key, value);
map.put(key, newNode);
insertToFirst(newNode);
size++;
if (size > capacity) { // 超出了容量。
int tmp = tail.pre.key;
map.remove(tmp);
deleteLast();
size--;
}
} else { // 链表中已经有这个key了。
node.value = value;
moveToFirst(node);
}
}
// 删除最后一个结点。
private void deleteLast() {
remove(tail.pre);
}
// 将一个node,移出来,然后发到头部。
private void moveToFirst(Node node) {
remove(node);
insertToFirst(node);
}
// 将一个node插到头部。
private void insertToFirst(Node node) {
node.next = head.next;
node.pre = head;
head.next.pre = node;
head.next = node;
}
// 将一个node移出
private void remove(Node node) {
node.pre.next = node.next;
node.next.pre = node.pre;
}
}