用HashMap实现简单缓存需手动管理过期与淘汰:封装HashMap、添加时间戳、懒清理过期项、可选LRU踢出、推荐ConcurrentHashMap保障线程安全,长期运行需增量清理。

用 HashMap 实现简单缓存,核心是手动管理键值对的存取和过期逻辑——HashMap 本身不支持自动过期或容量淘汰,所以得自己补上这些能力。
基础缓存结构:包装 HashMap
直接用 HashMap 不够安全,建议封装一层,隐藏内部操作,避免外部误改。例如:
public class SimpleCache<k v> {
private final Map<k cacheentry>> cache;
private final long expireMillis;
public SimpleCache(long expireMillis) {
this.cache = new HashMap();
this.expireMillis = expireMillis;
}
private static class CacheEntry<t> {
final T value;
final long createTime;
CacheEntry(T value) {
this.value = value;
this.createTime = System.currentTimeMillis();
}
}
}</t></k></k>
带过期检查的 get 和 put
每次读写都需判断是否过期,并清理无效条目。注意:懒清理(访问时才删)比定时线程更轻量,适合简单场景。
- get(K key):查到后先校验是否过期,过期则移除并返回 null
- put(K key, V value):直接覆盖旧值,无需判断过期(新值自带新时间戳)
- 可选:在 put 前检查 size 并触发简单 LRU 踢出(比如保留最近 100 条)
线程安全要考虑吗?
如果多个线程同时读写,HashMap 会出错。有几种轻量方案:
- 用
ConcurrentHashMap替代 HashMap,性能好、线程安全 - 读多写少时,加
synchronized方法锁(简单但吞吐低) - 不加锁 + 每次 get/put 都用
computeIfAbsent或replace等原子方法(推荐)
别忘了清理陈旧数据
长期运行下,过期项可能越积越多。可以加一个简易清理方法:
- 在
get或put里顺手扫描并删除一批过期项(比如每次最多删 5 个) - 避免全量遍历:用
Iterator.remove()安全删除,不抛 ConcurrentModificationException - 真正高要求场景,就该换
Caffeine或Guava Cache——它们内置了刷新、淘汰、统计等完整能力
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











