linkedhashmap 通过设置 accessorder=true 并重写 removeeldestentry() 方法可天然实现 lru 缓存:访问或插入时自动调整节点至链表尾,淘汰时移除头节点;该方法仅在 put/putall 后触发,返回 true 时删除最老项。

LinkedHashMap 通过重写 removeEldestEntry() 方法,配合访问顺序模式(accessOrder = true),天然支持 LRU 缓存逻辑。它不需要手动维护时间戳或额外队列,底层利用双向链表维护元素访问顺序,最近访问的节点自动移到链表尾部,最久未用的自然留在头部,淘汰时只需移除头节点。
启用访问顺序模式
构造 LinkedHashMap 时必须传入 accessOrder = true,否则默认按插入顺序排列,无法实现 LRU:
new LinkedHashMap<k>(initialCapacity, loadFactor, true)</k>- 开启后,每次
get()或put()已存在 key 都会把对应节点移到链表末尾 - 插入新 key 则直接追加到尾部
重写 removeEldestEntry() 控制缓存容量
该方法在每次 put() 后被调用,返回 true 时自动删除最老(即链表头部)的映射:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 覆盖时判断当前 size 是否超过阈值,例如:
return size() > capacity; - 注意:该方法只对
put()触发,putAll()也会触发,但get()不会触发删除 - 若需在 get 时也检查容量(极少见),需自行封装逻辑
LRU 缓存的完整写法示例
以下是一个线程不安全但简洁的 LRU 缓存实现:
class LRUCache<k v> extends LinkedHashMap<k v> {
private final int capacity;
public LRUCache(int capacity) {
// accessOrder = true 启用访问顺序
super(16, 0.75f, true);
this.capacity = capacity;
}
@Override
protected boolean removeEldestEntry(Map.Entry<k v> eldest) {
return size() > capacity; // 超过容量就删最老的
}
}
</k></k></k>
使用时:LRUCache<string integer> cache = new LRUCache(3);</string>,后续 put 和 get 即自动满足 LRU 行为。
注意事项与边界情况
- LinkedHashMap 的迭代顺序就是访问顺序,遍历时最先遇到的是最久未用项
- 如果只读不写(纯 get),不会触发淘汰;只有 put 导致 size 增加时才检查并可能删除
- 若需线程安全,应在外层加锁(如
synchronized),或改用ConcurrentHashMap + 手动链表—— 此时 LinkedHashMap 不再适用 - key 重复
put属于“更新”,会触访问顺序移动,不增加 size,也不会触发removeEldestEntry
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










