linkedhashmap默认按插入顺序排列,启用访问顺序需构造时设accessorder=true;仅get已有key和put更新已有key会触发节点移至尾部;配合重写removeeldestentry可实现lru缓存。

LinkedHashMap 默认按插入顺序排列,要启用访问顺序(即 LRU 行为),必须在构造时显式指定 accessOrder = true。这不是默认行为,也不能在创建后动态修改。
用构造函数开启访问顺序
调用带三个参数的构造方法,将第三个布尔参数设为 true:
new LinkedHashMap<k>(initialCapacity, loadFactor, true)</k>- 常用简写:
new LinkedHashMap(16, 0.75f, true) - 不传第三个参数或传
false,都维持插入顺序
访问顺序生效的具体操作
只有以下两类操作会触发节点移到链表尾部(体现“最近访问”):
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
get(key):对已存在的 key 调用,对应 entry 移至末尾 -
put(key, value):更新已有 key 的值时,该 entry 也移至末尾 - 注意:
put新 key 是插入操作,加在尾部,不触发“移动”逻辑 -
get不存在的 key 返回null,不抛异常,也不改变顺序
配合 removeEldestEntry 实现 LRU 缓存
仅开启 accessOrder = true 还不够,需重写 removeEldestEntry 方法来自动淘汰最久未使用的项(链表头):
- 该方法在每次
put()后被调用,传入当前最老的 entry(链表头) - 返回
true才真正删除它;典型写法:return size() > MAX_CAPACITY; - 必须搭配
accessOrder = true,否则删掉的是最早插入而非最久未用的项
使用时要注意的细节
访问顺序模式下有几点容易踩坑:
- 遍历时顺序是动态的:每次
get或put都会改变链表结构 - 单线程中边遍历边调用
get可能触发ConcurrentModificationException - 它不是线程安全的,高并发场景建议用 Caffeine 或
ConcurrentHashMap自行维护顺序 -
keySet()、values()、entrySet()三者遍历顺序完全一致
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










