为什么有些情况下需要重写equals()和hashCode()方法?

目录

    • 方法作用
    • 实战案例

方法作用

  • equals():判断对象是否相等,比如判断是否能放入Set集合中
    • 情况1:没有重写equals()方法:由于所有类的默认基类都是Object类,所以默认使用Object类的equals()方法,那就是对象的引用地址
    • 情况2:重写equals()方法:用重写equals()方法进行判断两个对象是否相等
  • hashCode():决定对象存储位置,比如在Set集合中的存储位置
    - 没有重写hashCode()方法:由于所有类的默认基类都是Object类,所以默认使用Object类的hashCode()方法,那就该对象默认的hashcode
    - 重写hashCode()方法:用重写hashCode()方法来决定对象放置位置

实战案例

我目前在看开源项目tduck-platform,然后想了解一下问卷调查的周收集趋势是如何生成的,效果图如下:

为什么有些情况下需要重写equals()和hashCode()方法?_第1张图片
其实可以想到需要在查询数据库的时候需要按照“年月日”方式进行聚合,但是这样只能获取到有数据的情况,但是你可以看到上面例如2023-05-30是0,这种情况肯定不存在聚合结果中的,所以我们需要对聚合结果进行填充0操作,最常想到的方式是遍历这几天,看一下这一天是否已经存在了,存在就不填充了,否则就填充,基本也是这个意思,但是判断就需要使用到if语句,不是特别优雅,我们看一个优雅的操作,代码如下:

备注:具体代码路径

// 获取当前日期
Date now = new Date();
// 获取本周开始时间
DateTime startTime = DateUtil.beginOfWeek(now);
// 获取本周结束时间
DateTime endTime = DateUtil.endOfWeek(now);
// 获取本周的统计数据,注意人家在sql语句中用到了WHERE create_time >= YEARWEEK(now())
1Set<SituationVO> reportSituations = formDashboardMapper.selectFormReportSituation(formKey);
// 将本周的天数情况罗列一下
2List<DateTime> dateTimes = DateUtil.rangeToList(startTime, endTime, DateField.DAY_OF_WEEK);
// 填充不存在的天数情况,这块是最优秀的,我们下面好好分析
3、dateTimes.forEach(time -> {
    reportSituations.add(new SituationVO(time.toString(DatePattern.NORM_DATE_PATTERN), 0));
});
// 按照创建时间进行升序排序
return CollectionUtil.sort(reportSituations, (o1, o2) -> DateUtil.parse(o1.getCreateTime(), DatePattern.NORM_DATE_PATTERN)
        .isAfter(DateUtil.parse(o2.getCreateTime(), DatePattern.NORM_DATE_PATTERN)) ? 1 : -1);

上面提到的SituationVO就是本次讲解的重点,我们看一下该类内部信息,如下:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class SituationVO {
    private String createTime;

    private Integer count;


    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        SituationVO situation = (SituationVO) o;
        return Objects.equal(createTime, situation.createTime);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(createTime);
    }
}

可以看到equals()方法被重写了,通过createTime来判断两个SituationVO对象是否相等,就我们上面的例子来看,位置1已经生成了SituationVO对象的Set集合,位置2生成了本周的所有天数信息,位置3遍历本周的天气信息,然后往Set集合reportSituations中填充其他SituationVO对象,由于Set集合中元素不能重复,所以会判断SituationVO对象是否重复,由于我们重写了SituationVO类的equals()方法,所以createTime相同的SituationVO对象就不会在写入了,这就会完成填充0操作

你可能感兴趣的:(java学习之路,java,jvm,开发语言)