一次未重写父类hashCode和equal方法引发的线上问题

问题描述

定义一个集合用它来收集一些特殊对象,后续对集合中的元素做操作。 集合是一个HashSet,上线后发现异常,有些应该进去的偏偏进不去。 分析过程因为代码中使用到了RedisTemplate的HashOperations,因为我每次操作都是同一个HashOperations对象,所以开始怀疑HashOperations不是线程安全的,后面证实它在并发环境下没有问题。 于是线下模拟一遍, 发现HashSet永远只有一个,但是其实每次add进去的都是新的,为什么没有新增? 后面才发现原来自定义对象没有重写其父类的hashCodeequal方法。

定义类DownloadFinished,它继承一个父类BaseEntity

@Getter
@Setter
public class DownloadFinished extends BaseEntity {

    private Integer cd;

    private Long ruleId;

    private Object busId;
}

BaseEntity

@Data
public class BaseEntity implements Serializable {

    @TableId(type = IdType.AUTO)
    private Long id;

    private Date createTime;

    private Integer createBy;

    private Date updateTime;

    private Integer updateBy;
    @TableLogic
    private Long isDeleted;

    public Long getDeleted() {
        return isDeleted;
    }

    public void setDeleted(Long deleted) {
        isDeleted = deleted;
    }
}
    public static void main(String[] args) {
        Collection<DownloadFinished> finishedSet = Sets.newHashSet();

        for (int i = 0; i < 2; i++) {
            DownloadFinished finished = new DownloadFinished();
            finished.setCampaignId(i);
            finished.setVehicleId(i + 1);
            finishedSet.add(finished);
        }

        System.out.println(finishedSet);
        System.out.println(finishedSet.size());
    }

在这里插入图片描述
finishedVehicle集合应该有两个才对,但是只有一个。
因为HashSet底层还是用HashMap来实现的,所以判断两个对象是否一致会去看hashCode方法,因为DownloadFinished 没有重写父类BaseEntity的hashCode方法,又因父类属性没有改变,所以每次都当做是一样的了。

稍微调整后

@Getter
@Setter
@EqualsAndHashCode
public class DownloadFinished extends BaseEntity {

    private Integer cd;

    private Long ruleId;

    private Object busId;
}

直接使用lombok注解**@EqualsAndHashCode**来实现hashCode和equal方法的重写。

再次运行:
在这里插入图片描述
本来是很简单很基础的问题,但是自己却忽略了,归根到底还是因为自己没有深入理解其中的含义。 这块后续需加强JDK基础学习,深入JDK源码分析…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值