本文介绍两种高效方式:使用 stream 重建过滤后的新 hashmap,或通过 iterator 原地安全删除过期条目,避免并发修改异常,并提供可直接运行的 java 示例与关键注意事项。
在处理嵌套 HashMap> 结构时,若需根据内层 Map 中 “date” 字段的值(ISO 8601 格式时间戳)判断是否过期,并据此从外层 Map 中移除整个父键(如 “1#100″),必须注意 Java 集合的线程安全性和迭代中修改的限制——直接在 forEach 中调用 remove() 会抛出 ConcurrentModificationException。
✅ 推荐方案一:Stream + Collect(函数式、不可变风格)
该方式创建一个全新 HashMap,仅保留满足日期条件的条目,语义清晰、线程安全,适合数据量适中且可接受内存开销的场景:
// 定义过期判断逻辑:保留 date 晚于当前时刻的条目
Predicate isNotExpired = dateStr -> {
try {
return Instant.parse(dateStr).isAfter(Instant.now());
} catch (DateTimeParseException e) {
// 日志警告:跳过非法日期格式条目
System.err.println("Invalid date format: " + dateStr);
return false;
}
};
// 过滤并重建 map
h = h.entrySet().stream()
.filter(entry -> isNotExpired.test(entry.getValue().get("date")))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(v1, v2) -> v1, // 冲突时保留第一个值(理论上 key 不重复)
HashMap::new
));
⚠️ 注意:Timestamp.valueOf() 不支持带 Z 的 ISO 8601 字符串(如 “2023-02-03T10:00:00.907Z”),应统一使用 Instant.parse() 解析,更准确、无需手动处理时区。
✅ 推荐方案二:Iterator 原地删除(内存友好、高效)
当数据量极大或需最小化内存分配时,使用 Iterator 是最安全的原地删除方式: