1. 重写equals和hashCode区别
1.1 list中:不需要重写hashcode,重写会提高性能
重写equals是为了比较两个对象,目前需要在一个list中判断是否存在该对象
使用的是 clickRecordList.contains(clickRecord) ,这种情况其实是不需要重写hashCode的,list的contains中并没有利用hashcode去做比较
1.2 set和map中:需要重写hashcode
在set中,则是需要重写hashcode,set是不会将重复的对象添加进去,比较的是hashcode和equals,hashcode优先比较,而一般hashcode是对象的内存地址,自定义对象中需要重写不然每个对象内存地址都不同,到时equals不会生效。
@Test
public void contains(){
List<PacketClickRecord> clickRecordList = Lists.newArrayList(
new PacketClickRecord("a", "1"),
new PacketClickRecord("b", "2"),
new PacketClickRecord("b", "3")
);
PacketClickRecord clickRecord = new PacketClickRecord("b", "3");
if (clickRecordList.contains(clickRecord)){
System.out.println("重写equals成功");
}
}
@Test
public void hashset(){
HashSet set = Sets.newHashSet(
new PacketClickRecord("a", "1"),
new PacketClickRecord("b", "2"),
new PacketClickRecord("b", "3")
);
// 没有重写hashcode时,该对象能够添加进去
PacketClickRecord clickRecord = new PacketClickRecord("b", "3");
set.add(clickRecord);
System.out.println(set.size());
set.forEach(System.out::println);
}
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class PacketClickRecord {
private Integer clickRecord;
private String openId;
private Integer userAwardId;
private String day;
private String awardType;
private String ortherDetail;
@JsonIgnore
private Date createdTime;
@JsonIgnore
private Date updatedTime;
public PacketClickRecord(String openId, String awardType){
this.openId = openId;
this.awardType = awardType;
}
@Override
public int hashCode() {
return this.openId.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (obj instanceof PacketClickRecord){
PacketClickRecord clickRecord = (PacketClickRecord)obj;
if (clickRecord.getOpenId().equals(this.openId) && clickRecord.getAwardType().equals(this.awardType)){
return true;
}
}
return false;
}
}
2. 重写hashcode:提高性能
重写hashcode是为了提高性能,比如在HashSet或者HashMap场景中,添加一个对象进去是会先判断hashcode是否相同,相同再判断equals,这里面hashcode涉及到两个作用
① 若不重写hashcode,Object的hashcode是内存地址,每个对象实例是不同的,重写equals方法也没用,重复的元素还是会添加进去的
② 提高搜索效率:set在add前需要判断元素是否在当前set中已存在,若是通过equals方法比较,则是线性查找,有1000个元素的话,则要查找1000次,而使用hashcode则是在set内部维护一个table保存hashcode,先校验hashcode是否相同,校验次数就是桶bucket个数,能减少原本全部元素线性遍历的代价