您的位置:首页 > 职场人生

常见面试题之操作系统中的LRU缓存机制实现

2020-08-24 01:23 1006 查看

LRU缓存机制,全称Least Recently Used,字面意思就是最近最少使用,是一种缓存淘汰策略。换句话说,LRU机制就是认为最近使用的数据是有用的,很久没用过的数据是无用的,当内存满了就优先删除很久没有使用的数据

基于LeetCode146,可以使用哈希链表或者自定义双端链表类+哈希表两种方法来实现LRU缓存机制。

它应该支持以下操作:获取数据

get
和 写入数据
put

获取数据

get(key)
:如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回
-1

写入数据
put(key, value)
:如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。

1. 基于LinkedHashMap实现LRU缓存机制

class LRUCache {
Map<Integer, Integer> map;
int capacity;

public LRUCache(int capacity) {
this.capacity = capacity;
map = new LinkedHashMap<>();
}

public int get(int key) {
// 若key不存在返回-1
if(!map.containsKey(key)) return -1;
// 若key存在则获取key对应的val
int val = map.get(key);
// 更新位置
put(key, val);
return val;
}

public void put(int key, int val) {
// 若缓存命中则先删除数据在重新放入以更新位置
if(map.containsKey(key)) {
map.remove(key);
map.put(key, val);
} else {
// 若缓存未命中则先判断是否达到最大容量
// 超出容量则删除最久没有使用的数据(利用迭代器删除第一个)
if (capacity == map.size()) map.remove(map.keySet().iterator().next());
// 删除完成后存放新数据
map.put(key, val);
}
}
}

2. 基于DoubleList与HashMap实现LRU缓存机制

如果不使用LinkedHashMap,可以自己造轮子,自定义

DoubleList
类并结合
HashMap
实现与LinkedHashMap相同的功能。

class LRUCache {
int capacity;
DoubleList cache;
Map<Integer, Node> map;

public LRUCache(int capacity) {
this.capacity = capacity;
cache = new DoubleList();
map = new HashMap<>();
}

public int get(int key) {
if(!map.containsKey(key)) return -1;
int val = map.get(key).val;
put(key, val);
return val;
}

public void put(int key, int val) {
Node node = new Node(key, val);
if(map.containsKey(key)) {
cache.remove(map.get(key));
cache.addFirst(nod
1340
e);
map.put(key, node);
} else {
if(capacity == cache.size) map.remove(cache.removeLast().key);
cache.addFirst(node);
map.put(key, node);
}
}
}

class DoubleList {
Node head, tail;
int size;

public DoubleList() {
head = new Node(0, 0);
tail = new Node(0, 0);
head.next = tail;
tail.prev = head;
size = 0;
}

public void addFirst(Node node) {
Node temp = head.next;
node.next = temp;
temp.prev = node;
head.next = node;
node.prev = head;
size++;
}

public void remove(Node node) {
Node temp = node.prev;
temp.next = node.next;
temp.next.prev = temp;
size--;
}

public Node removeLast() {
if (size == 0) return null;
Node del = tail.prev;
remove(del);
return del;
}
}

class Node {
int key, val;
Node prev, next;

public Node(int key, int val) {
this.key = key;
this.val = val;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: