

方法一:使用 LinkedHashMap
public class LRUCache{
int capacity;
Map<Integer, Integer> map;
public LRUCache(int capacity) {
this.capacity = capacity;
map = new LinkedHashMap<>();
}
public int get(int key) {
if (!map.containsKey(key)) {
return -1;
}
// 先删除旧的位置,再放入新位置
Integer value = map.remove(key);
map.put(key, value);
return value;
}
public void put(int key, int value) {
if (map.containsKey(key)) {
map.remove(key);
map.put(key, value);
return;
}
map.put(key, value);
// 超出capacity,删除最久没用的,利用迭代器删除第一个
if (map.size() > capacity) {
map.remove(map.entrySet().iterator().next().getKey());
}
}
}
如果面试管要求不能使用LinkedHashMap,那么,
方法二:使用双链表+HashMap
- 底层应该用链表,按照数据的新旧程度来排列,旧的在右边,新的在左边,新来一个加到头部(你可以想象自己从有往左画一条链表),删除是删尾,除了这两个操作,还有就是把一个数据从中间拿出来放头上(这个数组就很难做到)
- 这里还有一个需求,就是要知道这个数据有没有存在于链表中,如果不在链表中,加到头即可,如果已经在链表中,就只要更细数据的位置,如何查找这个数据在不在呢,这就用哈希表。
- 考虑删除操作,要把当前节点的前一个节点的指针的改变,获取它前一个节点,方便的数据结构就是 双向链表。
这里我采用头插法来解决:
在插入的时候,首先判断map里的值,是否放满了,如果没有,那么还需要判断该值是否在链表中存在,如果存在,先删除在重新插入,如果不存在,那么直接插入。如果map满了,也有两种情况,一种时候,插入的值存在,那么更新一下,先删除,在插到头里,如果不存在,那么就要先移除尾巴上最不常用的,然后再插入到头!
在get获取的时候,首先判断map里是否存在,不存在,返回-1,如果存在,更新当前节点,先删除,然后,再加入到头


然后根据map的大小,来进行插入,删除,和获取就好了
class LRUCache {
class Node{
public int key;
public int val;
public Node pre;
public Node next;
public Node(int key,int val){
this.key = key;
this.val = val;
}
}
Map<Integer,Node> map = new HashMap<>();
int x ;
Node head = new Node(-1,-1);
Node tail = new Node(-1,-1);
public LRUCache(int capacity) {
this.x = capacity;
head.next = tail;
tail.pre = head;
}
public int get(int key) {
if(map.containsKey(key)){
int sum = map.get(key).val;
delete(key);
add(key,sum);
return sum;
}
return -1;
}
public void put(int key, int value) {
if(map.size() < x){
if(map.containsKey(key)){
delete(key);
add(key,value);
}else{
add(key,value);
}
}else{
if(map.containsKey(key)){
delete(key);
add(key,value);
}else{
Node node = tail.pre;
Node cur = node.pre;
tail.pre = cur;
cur.next = tail;
map.remove(node.key);
add(key,value);
}
}
}
public void delete(int key){
Node cur = map.get(key);
Node node2 = cur.next;
Node node1 = cur.pre;
node1.next = node2;
node2.pre = node1;
map.remove(key);
}
public void add(int key,int value){
Node cur = head.next;
Node node = new Node(key,value);
head.next = node;
node.pre = head;
node.next = cur;
cur.pre = node;
map.put(key,node);
}
}
本文介绍了如何使用Java实现LRU(Least Recently Used)缓存机制,主要讲解了两种方法:一是利用LinkedHashMap,二是结合双链表和HashMap。在不允许使用LinkedHashMap的情况下,通过双链表维护数据的新旧顺序,利用HashMap进行快速查找,当缓存满时,采用头插法更新并删除最不常用的数据。
680

被折叠的 条评论
为什么被折叠?



