思路:
方法1:
Java自带的LinkedHashMap实现了LRU。构造函数有三个参数。 LinkedHashMap<Integer, String> map = new LinkedHashMap<>(16, 0.75f, true);
分别是初始化容量,负载因子,排序模式,排序模式为true的时候是按照访问顺序排序就是LRU,默认按照插入顺序排序。
重写removeEldestEntry(Map.Entry<Integer, Integer> eldest)方法可以限制大小,判断是否需要移除最老的元素(最不经常使用的元素)。
方法2:
实现一个双向链表,实现队首插入结点,删除特定结点,结点移动至队首,删除队尾结点。
使用HashMap维护key和对应结点在双向链表中的位置。
get元素的时候,先通过HashMap获取结点的位置,然后再返回值,最后将结点移动至队首。
put元素的时候,先通过HashMap获取结点的位置,如果存在,修改完结点值后移动至队首,如果不存在,就创建结点放入HashMap中并再队首插入结点,如果插入后的大小超过最大的大小就把队尾的结点删除,并移除HashMap中对应的元素。
代码:
方法1;
class LRUCache extends LinkedHashMap<Integer, Integer>{
private int capacity;
public LRUCache(int capacity) {
super(capacity, 0.75F, true);
this.capacity = capacity;
}
public int get(int key) {
return super.getOrDefault(key, -1);
}
public void put(int key, int value) {
super.put(key, value);
}
protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
return size() > capacity;
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/
方法2:
class LRUCache {
class Node {
int key;
int val;
Node pre;
Node next;
public Node(){};
public Node(int key, int value){
this.key = key;
this.val = value;
}
}
private void addToHead(Node node) {
node.pre = head;
node.next = head.next;
node.next.pre = node;
head.next = node;
}
private void removeNode(Node node) {
node.pre.next = node.next;
node.next.pre = node.pre;
}
private void moveToHead(Node node) {
removeNode(node);
addToHead(node);
}
private Node removeTailPre() {
Node tailPre = tail.pre;
removeNode(tailPre);
return tailPre;
}
private Map<Integer, Node> cache = new HashMap<>();
private int size;
private int capacity;
private Node head, tail;
public LRUCache(int capacity) {
this.size = 0;
this.capacity = capacity;
head = new Node();
tail = new Node();
head.next = tail;
tail.pre = head;
}
public int get(int key) {
Node t = cache.get(key);
if(t == null) return -1;
moveToHead(t);
return t.val;
}
public void put(int key, int value) {
Node t = cache.get(key);
if(t == null) {
Node newNode = new Node(key, value);
cache.put(key, newNode);
addToHead(newNode);
size++;
if(size > capacity) {
Node tailPre = removeTailPre();
cache.remove(tailPre.key);
size--;
}
}
else {
t.val = value;
moveToHead(t);
}
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/
参考: