【Java】LinkedHashMap (LRU)淘汰缓存的使用

文章目录

      • [**1. `initialCapacity`(初始容量)**](#1. initialCapacity(初始容量))
      • [**2. `loadFactor`(加载因子)**](#2. loadFactor(加载因子))
      • [**3. `accessOrder`(访问顺序)**](#3. accessOrder(访问顺序))
      • **完整参数解释示例**
      • **示例验证**

LinkedHashMap 在 Java 中可维护元素插入或访问顺序,并实现 LRU 缓存,适用于有序存储数据和缓存管理场景。

在 Java 中,LinkedHashMap 的构造函数可以接受三个参数,分别是 initialCapacityloadFactoraccessOrder。以下是具体含义:


1. initialCapacity(初始容量)

  • 含义 :指定 LinkedHashMap 的初始容量,也就是可以存储的键值对的数量。
  • 默认值 :默认初始容量是 16
  • 工作机制 :当存储的键值对数量超过容量的 loadFactor 阈值时,LinkedHashMap 会自动扩容。
  • 设置建议:如果预估可以存储的键值对数量,可以设置为大于等于预估值。否则,系统在达到阈值时会进行扩容,可能影响性能。

示例

java 复制代码
new LinkedHashMap<>(16, 0.75f, true); // 初始容量为 16

2. loadFactor(加载因子)

  • 含义 :定义 LinkedHashMap 的扩容触发条件,计算公式为: 扩容阈值=initialCapacity×loadFactor\text{扩容阈值} = \text{initialCapacity} \times \text{loadFactor}
  • 默认值0.75
  • 工作机制 :当存储的键值对数量超过扩容阈值时,LinkedHashMap 会将容量增加一倍(重新哈希)。
  • 设置建议
    • 较低的加载因子(如 0.5):减少冲突,但会增加内存占用。
    • 较高的加载因子(如 1.0):节省内存,但会增加冲突概率,影响性能。

示例

java 复制代码
new LinkedHashMap<>(16, 0.75f, true); // 加载因子为 0.75,扩容阈值为 16 × 0.75 = 12

3. accessOrder(访问顺序)

  • 含义 :定义键值对的迭代顺序:
    • false(默认值):按照插入顺序排序(插入顺序)。
    • true:按照访问顺序排序(最近访问的在后面)。
  • 工作机制 :如果 accessOrder 设置为 true,每次访问(包括 getput 操作)会将该键值对移动到双向链表的尾部,从而保证最近访问的元素总是位于链表末尾。
  • 使用场景
    • 如果需要实现 LRU 缓存 (Least Recently Used),设置 accessOrder = true
    • 如果不需要按访问顺序排序,可以省略该参数或设置为 false

示例

java 复制代码
new LinkedHashMap<>(16, 0.75f, true); // 按访问顺序排序

完整参数解释示例

java 复制代码
LinkedHashMap<String, Integer> map = new LinkedHashMap<>(16, 0.75f, true);
  1. initialCapacity = 16:初始可以存储最多 16 个键值对。
  2. loadFactor = 0.75f:扩容阈值为 16×0.75=1216 \times 0.75 = 12,当存储键值对超过 12 时触发扩容。
  3. accessOrder = true:按访问顺序排序,最近访问的键值对会移动到链表末尾。

示例验证

以下代码展示了 accessOrder = true 的效果:

java 复制代码
import java.util.LinkedHashMap;
import java.util.Map;

public class AccessOrderTest {
    public static void main(String[] args) {
        Map<String, Integer> map = new LinkedHashMap<>(16, 0.75f, true);

        map.put("A", 1);
        map.put("B", 2);
        map.put("C", 3);

        System.out.println("Initial: " + map);

        // 访问 "A"
        map.get("A");
        System.out.println("After accessing A: " + map);

        // 插入新元素 "D"
        map.put("D", 4);
        System.out.println("After inserting D: " + map);
    }
}

输出结果

复制代码
Initial: {A=1, B=2, C=3}
After accessing A: {B=2, C=3, A=1}
After inserting D: {B=2, C=3, A=1, D=4}

解释

  • 初始状态:A -> B -> C,按照插入顺序。
  • 访问 A 后:B -> C -> AA 被移到链表末尾。
  • 插入 D 后:B -> C -> A -> D,新键值对始终追加到尾部。

相关推荐
记得开心一点嘛2 小时前
Redis封装类
java·redis
短剑重铸之日2 小时前
《7天学会Redis》Day 5 - Redis Cluster集群架构
数据库·redis·后端·缓存·架构·cluster
lkbhua莱克瓦242 小时前
进阶-存储过程3-存储函数
java·数据库·sql·mysql·数据库优化·视图
计算机程序设计小李同学2 小时前
基于SSM框架的动画制作及分享网站设计
java·前端·后端·学习·ssm
鱼跃鹰飞2 小时前
JMM 三大特性(原子性 / 可见性 / 有序性)面试精简版
java·jvm·面试
jghhh012 小时前
传递对准MATLAB仿真程序
开发语言·matlab
该怎么办呢3 小时前
基于cesium的三维不动产登记系统的设计与实现(毕业设计)
java·毕业设计
J不A秃V头A3 小时前
多任务执行时,共享请求对象被并发修改
java
heartbeat..3 小时前
零基础学 SQL:DQL/DML/DDL/DCL 核心知识点汇总(附带连接云服务器数据库教程)
java·服务器·数据库·sql
编程武士3 小时前
Python 各版本主要变化速览
开发语言·python