java lru队列_具有泛型和O(1)操作的Java中的LRU缓存

从问题本身,我们可以看到O(n)操作的问题在查询链表时出现.因此,我们需要一个替代的数据结构.我们需要能够从HashMap更新项目的最后访问时间,而无需搜索.

我们可以保留两个单独的数据结构.具有(键,指针)对的HashMap和双向链表,将作为删除和存储值的优先级队列.从HashMap中,我们可以指向双向链表中的一个元素,并更新其检索时间.因为我们直接从HashMap到列表中的项目,所以我们的时间复杂度保持在O(1)

例如,我们的双向链表可能如下所示:

least_recently_used -> A B C D E

我们需要保留指向LRU和MRU项目的指针.条目值将存储在列表中,当我们查询HashMap时,我们将获得一个指向列表的指针.在get()上,我们需要将该项目放在列表最右侧.在put(key,value)上,如果缓存已满,我们需要从列表和HashMap中删除列表最左侧的项.

以下是Java中的示例实现:

public class LRUCache{

// Define Node with pointers to the previous and next items and a key, value pair

class Node {

Node previous;

Node next;

T key;

U value;

public Node(Node previous, Node next, T key, U value){

this.previous = previous;

this.next = next;

this.key = key;

this.value = value;

}

}

private HashMap> cache;

private Node leastRecentlyUsed;

private Node mostRecentlyUsed;

private int maxSize;

private int currentSize;

public LRUCache(int maxSize){

this.maxSize = maxSize;

this.currentSize = 0;

leastRecentlyUsed = new Node(null, null, null, null);

mostRecentlyUsed = leastRecentlyUsed;

cache = new HashMap>();

}

public V get(K key){

Node tempNode = cache.get(key);

if (tempNode == null){

return null;

}

// If MRU leave the list as it is

else if (tempNode.key == mostRecentlyUsed.key){

return mostRecentlyUsed.value;

}

// Get the next and previous nodes

Node nextNode = tempNode.next;

Node previousNode = tempNode.previous;

// If at the left-most, we update LRU

if (tempNode.key == leastRecentlyUsed.key){

nextNode.previous = null;

leastRecentlyUsed = nextNode;

}

// If we are in the middle, we need to update the items before and after our item

else if (tempNode.key != mostRecentlyUsed.key){

previousNode.next = nextNode;

nextNode.previous = previousNode;

}

// Finally move our item to the MRU

tempNode.previous = mostRecentlyUsed;

mostRecentlyUsed.next = tempNode;

mostRecentlyUsed = tempNode;

mostRecentlyUsed.next = null;

return tempNode.value;

}

public void put(K key, V value){

if (cache.containsKey(key)){

return;

}

// Put the new node at the right-most end of the linked-list

Node myNode = new Node(mostRecentlyUsed, null, key, value);

mostRecentlyUsed.next = myNode;

cache.put(key, myNode);

mostRecentlyUsed = myNode;

// Delete the left-most entry and update the LRU pointer

if (currentSize == maxSize){

cache.remove(leastRecentlyUsed.key);

leastRecentlyUsed = leastRecentlyUsed.next;

leastRecentlyUsed.previous = null;

}

// Update cache size, for the first added entry update the LRU pointer

else if (currentSize < maxSize){

if (currentSize == 0){

leastRecentlyUsed = myNode;

}

currentSize++;

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值