我了解LRU缓存的原理。例如,请参见此处:https://java2blog.com/lru-cache-implementation-java/
然而,我很难理解在现实世界中如何解释这一点。例如,如果我想存储对象(没有自然编号/顺序(,我知道值(在hashmap中(只是指向链表中节点的指针,但键代表什么?
此外,node.value代表什么?我认为这是正在缓存的实际对象。但是,这与hashmap中的键是如何对应的呢?
一个典型的hashmap有一个键和一个值,它们都是任意类型的。键是您想要索引结构的对象,值是您想要存储和检索的对象。考虑Java中的一个普通哈希图:
Map<UUID, Person> peopleById = new HashMap<>();
您可以将UUID传递给.get
方法,并获取与该UUID关联的人员(如果存在(。
现实世界中使用的LRU缓存也是这样的:
Map<UUID, Person> cachedPeopleById = new LRUCache<>(10);
UUID是键,Person是值。
您链接到的引用实现不使用泛型,它只支持int
到int
,这相当于Map<Integer, Integer>
。引用实现中的Node
类不应该在公共方法中公开。因此,在该引用实现中,Node
应该是隐藏的,delete(Node)
和setHead(Node)
应该是私有的,因为否则它们将公开缓存的实现细节。
一个更好的实现应该是这样的(在我的脑海中做这件事,可能会有编译错误,仅用于说明目的(:
public class LRUCache <KeyType, ValueType> implements Map<KeyType, ValueType> {
private static class Node <KeyType, ValueType> {
KeyType key;
ValueType value;
Node prev;
Node next;
public Node(KeyType key, ValueType value){
this.key = key;
this.value = value;
}
}
int capacity;
HashMap<KeyType, Node> map = new HashMap<>();
Node head=null;
Node end=null;
public LRUCache(int capacity) {
this.capacity = capacity;
}
public ValueType get(KeyType key) {
...
}
public set(KeyType key, ValueType value) {
...
}
private void delete(Node<KeyType, ValueType> node) {
...
}
private void setHead(Node<KeyType, ValueType> node) {
...
}