从流数据源构造的Java不可变记录能否去重节省内存?
Java不可变记录去重节省内存方案
当然可以,HashMap是最直接的实现方式
你的场景完全适配:Java记录默认会基于所有字段生成正确的equals()和hashCode()方法,而且记录本身是不可变的,非常适合做实例缓存去重。
具体怎么做
- 维护一个缓存容器,比如
HashMap<YourRecord, YourRecord>,键和值存同一个实例 - 每次从流里解析出一条新记录后,调用
map.computeIfAbsent(newRecord, r -> r):- 如果缓存里已经有值相等的记录,直接返回已存在的实例
- 没有的话就把新实例放进缓存,返回它
- 这样所有值重复的记录都会复用同一个内存对象,内存占用会大幅降低
更优的选择
- 多线程场景用
ConcurrentHashMap:保证线程安全,避免并发问题 - 怕缓存占内存太久用
WeakHashMap:它的键是弱引用,当记录实例没有其他强引用时,GC会自动回收缓存里的条目,不会像字符串常量池那样一直占着内存 - 自定义缓存生命周期:比如按处理批次清理缓存,或者监控内存使用情况触发清理,比WeakHashMap更灵活
要注意的点
- 确保记录真的不可变:Java记录的字段默认是
final的,但如果字段是可变类型(比如ArrayList),内部状态仍可能被修改,会导致缓存实例出问题,所以尽量用不可变字段类型 - 不要乱改
equals()和hashCode():Java记录自动生成的这两个方法已经完全基于值相等判断,重写反而容易出错
内容的提问来源于stack exchange,提问作者iseki
相关产品推荐
相关产品推荐

