java如何实现一个LRU(最近最少使用)缓存? 要求:设计一个LRU缓存,支持get和put操作。当缓存满时,需要淘汰最近最少使用的元素。要求使用双向链表+哈希表的数据结构来实现,并保证get和put操作的时间复杂度为O(1)。

简介: java如何实现一个LRU(最近最少使用)缓存?要求:设计一个LRU缓存,支持get和put操作。当缓存满时,需要淘汰最近最少使用的元素。要求使用双向链表+哈希表的数据结构来实现,并保证get和put操作的时间复杂度为O(1)。

要实现一个LRU缓存,可以使用双向链表和哈希表。双向链表用于存储缓存中的元素,按照访问顺序进行排序;哈希表用于快速查找元素在双向链表中的位置。

以下是Java代码实现:

import java.util.HashMap;

public class LRUCache {
   
    private int capacity;
    private HashMap<Integer, Node> map;
    private Node head;
    private Node tail;

    public LRUCache(int capacity) {
   
        this.capacity = capacity;
        map = new HashMap<>();
        head = new Node(-1, -1);
        tail = new Node(-1, -1);
        head.next = tail;
        tail.prev = head;
    }

    public int get(int key) {
   
        if (map.containsKey(key)) {
   
            Node node = map.get(key);
            remove(node);
            add(node);
            return node.value;
        }
        return -1;
    }

    public void put(int key, int value) {
   
        if (map.containsKey(key)) {
   
            Node node = map.get(key);
            node.value = value;
            remove(node);
            add(node);
        } else {
   
            if (map.size() >= capacity) {
   
                map.remove(tail.prev.key);
                remove(tail.prev);
            }
            Node newNode = new Node(key, value);
            map.put(key, newNode);
            add(newNode);
        }
    }

    private void add(Node node) {
   
        Node next = head.next;
        head.next = node;
        node.prev = head;
        node.next = next;
        next.prev = node;
    }

    private void remove(Node node) {
   
        Node prev = node.prev;
        Node next = node.next;
        prev.next = next;
        next.prev = prev;
    }

    class Node {
   
        int key;
        int value;
        Node prev;
        Node next;

        public Node(int key, int value) {
   
            this.key = key;
            this.value = value;
        }
    }
}

在这个实现中,LRUCache类包含一个容量为capacity的哈希表map,以及两个指向双向链表头部和尾部的节点headtailget方法首先检查哈希表中是否存在指定的键,如果存在,则将对应的节点移动到双向链表的头部,并返回其值;否则返回-1。put方法首先检查哈希表中是否已存在指定的键,如果存在,则更新对应的节点的值,并将其移动到双向链表的头部;如果不存在,则创建一个新的节点,将其添加到哈希表和双向链表的头部。当添加新节点时,需要检查当前缓存的大小是否已达到容量上限,如果达到上限,则需要从双向链表的尾部移除最近最少使用的元素(即哈希表中对应的键),并从哈希表中删除该键。

相关文章
|
9天前
|
算法
数据结构:1、时间复杂度
数据结构:1、时间复杂度
16 1
|
2月前
|
机器学习/深度学习 存储 缓存
数据结构从入门到精通——算法的时间复杂度和空间复杂度
算法的时间复杂度和空间复杂度是评估算法性能的两个重要指标。时间复杂度主要关注算法执行过程中所需的时间随输入规模的变化情况,而空间复杂度则关注算法执行过程中所需的最大存储空间或内存空间。
74 0
|
2月前
|
存储 算法
数据结构——lesson1时间复杂度和空间复杂度
数据结构——lesson1时间复杂度和空间复杂度
|
2月前
|
机器学习/深度学习 算法 Windows
数据结构中的几种时间复杂度分析方式
数据结构中的几种时间复杂度分析方式
31 0
数据结构|双向链表|带头结点|头插|尾插|尾删|头删
数据结构|双向链表|带头结点|头插|尾插|尾删|头删
|
22天前
|
算法 数据处理 C语言
【数据结构与算法】快速排序(详解:快排的Hoare原版,挖坑法和双指针法|避免快排最坏时间复杂度的两种解决方案|小区间优化|非递归的快排)
【数据结构与算法】快速排序(详解:快排的Hoare原版,挖坑法和双指针法|避免快排最坏时间复杂度的两种解决方案|小区间优化|非递归的快排)
|
29天前
|
Java
Java编写Http的Get和Post请求示例代码
Java编写Http的Get和Post请求示例代码
26 2
|
2月前
|
存储
【双向链表】数据结构双向链表的实现
【双向链表】数据结构双向链表的实现
|
2月前
|
机器学习/深度学习 存储 缓存
数据结构--算法的时间复杂度和空间复杂度
数据结构--算法的时间复杂度和空间复杂度
|
2月前
|
存储
【数据结构】双向链表
【数据结构】双向链表