linkedhashmap 通过启用 accessorder=true 并重写 removeeldestentry() 方法天然支持 lru 缓存:插入或更新时节点移至尾部,头部为最久未使用项;该方法在每次 put 后触发,超容即删头节点,实现“最近访问优先保留”。

LinkedHashMap 通过重写 removeEldestEntry() 方法,配合访问顺序模式(accessOrder = true),天然支持 LRU 缓存淘汰逻辑。
启用访问顺序模式
构造 LinkedHashMap 时需显式传入 accessOrder = true,否则默认按插入顺序维护链表,无法实现“最近访问优先保留”:
- 插入新元素、调用
get()、put()更新已有 key,都会将对应节点移到链表尾部(即“最近访问”位置) - 链表头部始终是“最久未使用”的条目,适合淘汰
重写 removeEldestEntry() 控制缓存大小
该方法在每次 put() 或 putAll() 后被自动调用,返回 true 时会删除链表头部节点:
- 典型做法是判断当前 size 是否超过预设容量:
return size() > capacity; - 注意:它只在插入操作后触发,读取(
get())不会导致淘汰,符合 LRU 语义
完整 LRU 缓存示例
以下是一个线程不安全但结构清晰的 LRU 缓存实现:
class LRUCache<k v> extends LinkedHashMap<k v> {
private final int capacity;
public LRUCache(int capacity) {
// accessOrder = true 启用访问顺序
super(capacity, 0.75f, true);
this.capacity = capacity;
}
@Override
protected boolean removeEldestEntry(Map.Entry<k v> eldest) {
return size() > capacity; // 超过容量则移除最老项
}
}</k></k></k>
使用时只需 cache.put(key, value) 和 cache.get(key),内部自动完成排序与淘汰。
注意事项
- 非线程安全:高并发场景需额外同步(如包装为
Collections.synchronizedMap(),或改用ConcurrentHashMap + 显式链表) - 初始化容量建议略大于预期最大缓存数,避免频繁扩容影响链表顺序稳定性
-
removeEldestEntry()中不要执行耗时操作,否则拖慢所有put调用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











