如何使用泛型在 Java 中编写 LRU 缓存?

简介: 【8月更文挑战第22天】

LRU(最近最少使用)缓存是一种数据结构,它存储最近最少使用的元素,并在缓存已满时淘汰最旧的元素。使用泛型可以让你创建可存储任何类型对象的 LRU 缓存。

实现

以下是如何在 Java 中使用泛型实现 LRU 缓存:

import java.util.HashMap;
import java.util.Map;

public class LRUCache<K, V> {
   

    private final int capacity;
    private final Map<K, Node<K, V>> cache;
    private Node<K, V> head;
    private Node<K, V> tail;

    public LRUCache(int capacity) {
   
        this.capacity = capacity;
        this.cache = new HashMap<>();
    }

    public V get(K key) {
   
        Node<K, V> node = cache.get(key);
        if (node == null) {
   
            return null;
        }
        moveToHead(node);
        return node.value;
    }

    public void put(K key, V value) {
   
        Node<K, V> node = cache.get(key);
        if (node != null) {
   
            node.value = value;
            moveToHead(node);
            return;
        }
        node = new Node<>(key, value);
        cache.put(key, node);
        addToHead(node);
        if (cache.size() > capacity) {
   
            removeTail();
        }
    }

    private void moveToHead(Node<K, V> node) {
   
        if (node == head) {
   
            return;
        }
        if (node == tail) {
   
            tail = tail.prev;
            tail.next = null;
        } else {
   
            node.prev.next = node.next;
            node.next.prev = node.prev;
        }
        node.next = head;
        node.prev = null;
        head = node;
    }

    private void addToHead(Node<K, V> node) {
   
        if (head == null) {
   
            head = tail = node;
            return;
        }
        node.next = head;
        head.prev = node;
        head = node;
    }

    private void removeTail() {
   
        if (tail == null) {
   
            return;
        }
        cache.remove(tail.key);
        if (tail == head) {
   
            head = tail = null;
            return;
        }
        tail = tail.prev;
        tail.next = null;
    }

    private static class Node<K, V> {
   
        K key;
        V value;
        Node<K, V> prev;
        Node<K, V> next;

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

用法

以下是如何使用此 LRU 缓存:

LRUCache<String, Integer> cache = new LRUCache<>(3);

cache.put("key1", 1);
cache.put("key2", 2);
cache.put("key3", 3);

System.out.println(cache.get("key1")); // 输出:1
cache.put("key4", 4);

System.out.println(cache.get("key2")); // 输出:null

结论

使用泛型可以让你创建可存储任何类型对象的 LRU 缓存。这使得缓存更灵活,可以用于各种场景。

目录
相关文章
|
12月前
|
人工智能 算法 NoSQL
LRU算法的Java实现
LRU(Least Recently Used)算法用于淘汰最近最少使用的数据,常应用于内存管理策略中。在Redis中,通过`maxmemory-policy`配置实现不同淘汰策略,如`allkeys-lru`和`volatile-lru`等,采用采样方式近似LRU以优化性能。Java中可通过`LinkedHashMap`轻松实现LRUCache,利用其`accessOrder`特性和`removeEldestEntry`方法完成缓存淘汰逻辑,代码简洁高效。
559 0
|
8月前
|
安全 Java
Java之泛型使用教程
Java之泛型使用教程
460 10
|
10月前
|
安全 Java API
在Java中识别泛型信息
以上步骤和示例代码展示了怎样在Java中获取泛型类、泛型方法和泛型字段的类型参数信息。这些方法利用Java的反射API来绕过类型擦除的限制并访问运行时的类型信息。这对于在运行时进行类型安全的操作是很有帮助的,比如在创建类型安全的集合或者其他复杂数据结构时处理泛型。注意,过度使用反射可能会导致代码难以理解和维护,因此应该在确有必要时才使用反射来获取泛型信息。
320 11
|
缓存 算法 数据挖掘
深入理解缓存更新策略:从LRU到LFU
【10月更文挑战第7天】 在本文中,我们将探讨计算机系统中缓存机制的核心——缓存更新策略。缓存是提高数据检索速度的关键技术之一,无论是在硬件还是软件层面都扮演着重要角色。我们会详细介绍最常用的两种缓存算法:最近最少使用(LRU)和最少使用频率(LFU),并讨论它们的优缺点及适用场景。通过对比分析,旨在帮助读者更好地理解如何选择和实现适合自己需求的缓存策略,从而优化系统性能。
705 3
|
缓存 JavaScript 前端开发
Java 如何确保 JS 不被缓存
【10月更文挑战第19天】在 Java 中,可以通过设置 HTTP 响应头来确保 JavaScript 文件不被浏览器缓存。方法包括:1. 使用 Servlet 设置响应头,通过 `doGet` 方法设置 `Expires`、`Cache-Control` 和 `Pragma` 头;2. 在 Spring Boot 中配置拦截器,通过 `NoCacheInterceptor` 类和 `WebConfig` 配置类实现相同功能。这两种方法都能确保每次请求都能获取到最新的 JavaScript 内容。
240 1
|
存储 缓存 Java
Java中的分布式缓存与Memcached集成实战
通过在Java项目中集成Memcached,可以显著提升系统的性能和响应速度。合理的缓存策略、分布式架构设计和异常处理机制是实现高效缓存的关键。希望本文提供的实战示例和优化建议能够帮助开发者更好地应用Memcached,实现高性能的分布式缓存解决方案。
293 9
|
Java 语音技术 容器
java数据结构泛型
java数据结构泛型
207 5
|
存储 安全 Java
🌱Java零基础 - 泛型详解
【10月更文挑战第7天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
246 1
|
存储 Java 编译器
Java集合定义其泛型
Java集合定义其泛型
164 1