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