146. LRU 缓存https://leetcode.cn/problems/lru-cache/
请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现
LRUCache
类:
LRUCache(int capacity)
以 正整数 作为容量capacity
初始化 LRU 缓存int get(int key)
如果关键字key
存在于缓存中,则返回关键字的值,否则返回-1
。void put(int key, int value)
如果关键字key
已经存在,则变更其数据值value
;如果不存在,则向缓存中插入该组key-value
。如果插入操作导致关键字数量超过capacity
,则应该 逐出 最久未使用的关键字。函数
get
和put
必须以O(1)
的平均时间复杂度运行。示例:
输入 ["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"] [[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]] 输出 [null, null, null, 1, null, -1, null, -1, 3, 4] 解释 LRUCache lRUCache = new LRUCache(2); lRUCache.put(1, 1); // 缓存是 {1=1} lRUCache.put(2, 2); // 缓存是 {1=1, 2=2} lRUCache.get(1); // 返回 1 lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3} lRUCache.get(2); // 返回 -1 (未找到) lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3} lRUCache.get(1); // 返回 -1 (未找到) lRUCache.get(3); // 返回 3 lRUCache.get(4); // 返回 4
lass LRUCache extends LinkedHashMap{
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);
}
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > capacity;
}
}
以下是 LinkedHashMap
的一些关键特点和特性:
顺序保留: 正如前面提到的,LinkedHashMap
会保持元素的插入顺序。当您迭代一个 LinkedHashMap
时,元素将按照它们被添加的顺序返回。
性能: LinkedHashMap
提供了基本操作如 get
、put
等的常数时间性能,与标准的 HashMap
类似。
可访问性顺序: 除了维护插入顺序,LinkedHashMap
还支持可访问性顺序。这意味着当你访问一个已存在的映射条目时,它会将该条目移到最后,使得最近访问的元素位于迭代顺序的末尾。这对于实现基于访问频率的缓存非常有用。
允许空键和值: 与 HashMap
一样,LinkedHashMap
也允许存储空键和空值。
不同的迭代方式: LinkedHashMap
支持两种迭代方式,即迭代访问顺序和迭代插入顺序,你可以根据需要选择其中一种。
//capacity:长度
//0.75F:负载因子
//true:遍历顺序标志位
super(capacity, 0.75F, true);
/**
* Constructs an empty {@code LinkedHashMap} instance with the
* specified initial capacity, load factor and ordering mode.
*
* @param initialCapacity the initial capacity
* @param loadFactor the load factor
* @param accessOrder the ordering mode - {@code true} for
* access-order, {@code false} for insertion-order
* @throws IllegalArgumentException if the initial capacity is negative
* or the load factor is nonpositive
*/
public LinkedHashMap(int initialCapacity,
float loadFactor,
boolean accessOrder) {
super(initialCapacity, loadFactor);
this.accessOrder = accessOrder;
}
/**
*
* @param eldest The least recently inserted entry in the map, or if
* this is an access-ordered map, the least recently accessed
* entry. This is the entry that will be removed it this
* method returns {@code true}. If the map was empty prior
* to the {@code put} or {@code putAll} invocation resulting
* in this invocation, this will be the entry that was just
* inserted; in other words, if the map contains a single
* entry, the eldest entry is also the newest.
* @return
* LinkedHashMap自带的判断是否删除最老的元素方法,默认返回false,即不删除老数据;这里重写该方法
*/
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return size()>capacity;
}