Java Stream distinct()方法对ExpenseListingDTO列表去重失效问题
Stream distinct()去重失效的核心诱因
- 最常见的根本原因:
ExpenseListingDTO类未正确重写equals()和hashCode()方法。Java Stream的distinct()方法完全依赖对象的equals()方法判断两个元素是否相等,同时用hashCode()做前置哈希校验。如果该DTO没有重写这两个方法,会默认使用Object类的原生实现,仅对比对象的内存地址,哪怕两个DTO的所有业务属性值完全一致,只要是不同的实例对象,distinct()就会判定为不同元素,无法实现去重。 - 重写规则不匹配业务逻辑:重写的
equals()和hashCode()逻辑与业务上的“重复”判定标准不一致。比如业务上认为只要费用ID、费用类型两个字段相同就算重复,但重写方法时仅用到了主键ID字段,或者额外加入了总金额、创建时间这类动态变化的字段做判定,也会导致符合业务重复标准的对象被distinct()识别为不同元素。 - 动态属性赋值异常:如果
equals()方法的判定规则包含了代码中动态赋值的totalAmount字段,要确认totalAmount的赋值逻辑是否正确,避免本应属性一致的DTO因为赋值异常出现属性差异,导致distinct()判定不通过。 - 映射环节生成冗余实例:
expenseListMapper在做实体转DTO时,可能对同一个源ExpenseList实体生成了多个属性完全一致的DTO实例,会放大上述逻辑问题的影响。
内容的提问来源于stack exchange,提问作者sadpatato
相关产品推荐
相关产品推荐

