如何排除Caffeine缓存中作为Key的POJO属性参与HashCode计算
解决Caffeine缓存Key排除指定属性参与哈希计算的问题
核心问题分析
你提到缓存使用System.identityHashCode计算哈希值,这说明当前Caffeine配置是基于对象引用判断Key是否相等,而非对象的属性内容。要实现排除prop3参与哈希计算,需要两步:让Caffeine使用对象自定义的equals()和hashCode()方法,同时在DataKey中重写这两个方法,排除prop3的影响。
具体实现步骤
1. 调整Caffeine配置,使用自定义equals/hashCode
默认情况下,Caffeine会使用对象的equals()和hashCode(),但如果你的缓存配置了identityKeys()或weakKeys(),会强制依赖System.identityHashCode,需要移除这类配置:
Cache<DataKey, Object> cache = Caffeine.newBuilder() // 移除identityKeys()、weakKeys()这类依赖对象引用的配置 .maximumSize(1000) .build();
2. 重写DataKey的equals()和hashCode()方法
在DataKey中手动实现这两个方法,仅用prop1和prop2参与计算,排除prop3:
import java.util.Objects; class DataKey { private String prop1; private String prop2; private String prop3; // 构造方法、getter/setter自行补充 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; DataKey dataKey = (DataKey) o; // 仅比较prop1和prop2 return Objects.equals(prop1, dataKey.prop1) && Objects.equals(prop2, dataKey.prop2); } @Override public int hashCode() { // 仅基于prop1和prop2生成哈希值 return Objects.hash(prop1, prop2); } }
3. 验证效果
当两个DataKey对象的prop1和prop2完全相同,即使prop3取值不同,Caffeine也会判定它们为同一个Key,从而命中同一缓存条目。
特殊场景说明
如果业务必须保留identityKeys()或weakKeys()配置(比如需要基于对象引用做缓存),则无法通过属性排除实现需求——此时缓存完全依赖对象内存地址而非属性内容,这种情况下建议拆分出仅包含prop1、prop2的新类作为缓存Key。
内容的提问来源于stack exchange,提问作者Yoda
相关产品推荐
相关产品推荐

