# Java手写LRU缓存算法

Java手写LRU缓存算法

1. 算法思维导图

LRU缓存算法 实现原理 手写必要性 市场调查 实现介绍 详细步骤 步骤1 步骤2 步骤3 代码实现 函数1 函数2 函数3 总结与思维拓展 完整代码 代码行注释

2. 实现原理

LRU(Least Recently Used)缓存算法是一种常用的缓存淘汰策略,它的基本思想是根据数据的访问时间来进行淘汰,最近使用的数据被认为是将来也可能会被使用的,因此被保留,而较久未使用的数据被认为是将来可能不会再使用的,因此被淘汰。

3. 手写必要性

手写LRU缓存算法的必要性在于深入理解算法的实现原理和核心思想,同时可以根据实际需求进行优化和定制化,提高缓存的效率和命中率。

4. 市场调查

根据市场调查,LRU缓存算法在各个领域都有广泛的应用,特别适用于需要频繁读取和更新数据的场景,如数据库查询、网络请求、页面缓存等。同时,随着大数据和云计算的发展,对高效缓存算法的需求也越来越大。

5. 实现介绍

5.1 详细步骤

  1. 初始化缓存大小和哈希表
  2. 定义双向链表节点类
  3. 定义LRU缓存类,包括构造函数和核心方法
  4. 实现核心方法:
    1. 查询缓存:根据键值在哈希表中查找对应的节点,若存在则将节点移动到链表头部,并返回值;若不存在则返回-1。
    2. 更新缓存:根据键值在哈希表中查找对应的节点,若存在则更新节点值并将节点移动到链表头部;若不存在则创建新节点并将节点插入链表头部,同时在哈希表中添加新节点。
    3. 插入缓存:根据键值在哈希表中查找对应的节点,若存在则更新节点值并将节点移动到链表头部;若不存在则创建新节点并将节点插入链表头部,同时在哈希表中添加新节点。若缓存已满,则删除链表尾部节点,并在哈希表中删除对应的节点。
    4. 删除缓存:根据键值在哈希表中查找对应的节点,若存在则删除节点,并在哈希表中删除对应的节点。

5.2 代码实现

java 复制代码
// 双向链表节点类
class Node {
    int key;
    int value;
    Node prev;
    Node next;
    
    public Node(int key, int value) {
        this.key = key;
        this.value = value;
    }
}

// LRU缓存类
class LRUCache {
    private int capacity;
    private Map<Integer, Node> cache;
    private Node head;
    private Node tail;
    
    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.cache = new HashMap<>();
        this.head = new Node(0, 0);
        this.tail = new Node(0, 0);
        this.head.next = this.tail;
        this.tail.prev = this.head;
    }
    
    public int get(int key) {
        if (cache.containsKey(key)) {
            Node node = cache.get(key);
            moveToHead(node);
            return node.value;
        }
        return -1;
    }
    
    public void put(int key, int value) {
        if (cache.containsKey(key)) {
            Node node = cache.get(key);
            node.value = value;
            moveToHead(node);
        } else {
            Node newNode = new Node(key, value);
            cache.put(key, newNode);
            addToHead(newNode);
            if (cache.size() > capacity) {
                Node tailNode = removeTail();
                cache.remove(tailNode.key);
            }
        }
    }
    
    private void moveToHead(Node node) {
        removeNode(node);
        addToHead(node);
    }
    
    private void addToHead(Node node) {
        node.prev = head;
        node.next = head.next;
        head.next.prev = node;
        head.next = node;
    }
    
    private void removeNode(Node node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }
    
    private Node removeTail() {
        Node tailNode = tail.prev;
        removeNode(tailNode);
        return tailNode;
    }
}

6. 总结与思维拓展

通过手写LRU缓存算法,我们深入理解了其实现原理和核心思想。LRU缓存算法可以提高缓存的效率和命中率,适用于各种需要频繁读取和更新数据的场景。在实际应用中,我们可以根据具体需求进行优化和定制化,进一步提升算法的性能。

7. 完整代码

java 复制代码
// 双向链表节点类
class Node {
    int key;
    int value;
    Node prev;
    Node next;
    
    public Node(int key, int value) {
        this.key = key;
        this.value = value;
    }
}

// LRU缓存类
class LRUCache {
    private int capacity;
    private Map<Integer, Node> cache;
    private Node head;
    private Node tail;
    
    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.cache = new HashMap<>();
        this.head = new Node(0, 0);
        this.tail = new Node(0, 0);
        this.head.next = this.tail;
        this.tail.prev = this.head;
    }
    
    public int get(int key) {
        if (cache.containsKey(key)) {
            Node node = cache.get(key);
            moveToHead(node);
            return node.value;
        }
        return -1;
    }
    
    public void put(int key, int value){
            if (cache.containsKey(key)) {
                Node node = cache.get(key);
                node.value = value;
                moveToHead(node);
            } else {
                Node newNode = new Node(key, value);
                cache.put(key, newNode);
                addToHead(newNode);
                if (cache.size() > capacity) {
                    Node tailNode = removeTail();
                    cache.remove(tailNode.key);
                }
            }
        }
    
        private void moveToHead(Node node) {
            removeNode(node);
            addToHead(node);
        }
    
        private void addToHead(Node node) {
            node.prev = head;
            node.next = head.next;
            head.next.prev = node;
            head.next = node;
        }
    
        private void removeNode(Node node) {
            node.prev.next = node.next;
            node.next.prev = node.prev;
        }
    
        private Node removeTail() {
            Node tailNode = tail.prev;
            removeNode(tailNode);
            return tailNode;
        }
    }
相关推荐
吾日三省吾码13 分钟前
JVM 性能调优
java
LNTON羚通41 分钟前
摄像机视频分析软件下载LiteAIServer视频智能分析平台玩手机打电话检测算法技术的实现
算法·目标检测·音视频·监控·视频监控
弗拉唐1 小时前
springBoot,mp,ssm整合案例
java·spring boot·mybatis
oi772 小时前
使用itextpdf进行pdf模版填充中文文本时部分字不显示问题
java·服务器
少说多做3432 小时前
Android 不同情况下使用 runOnUiThread
android·java
知兀2 小时前
Java的方法、基本和引用数据类型
java·笔记·黑马程序员
哭泣的眼泪4082 小时前
解析粗糙度仪在工业制造及材料科学和建筑工程领域的重要性
python·算法·django·virtualenv·pygame
蓝黑20202 小时前
IntelliJ IDEA常用快捷键
java·ide·intellij-idea
Ysjt | 深2 小时前
C++多线程编程入门教程(优质版)
java·开发语言·jvm·c++