1、首先解释一下hashCode方法的作用:
通过调用对象的hashCode方法,可以得到该对象的hashCode值。对象的hashCode值默认为是其本身属性经哈希函数变换后得到的一个值,这个值并不等于该对象的内存地址,但决定了该对象内存地址的分配。因此,不同引用地址的对象的hashCode值绝对是不相等的,除非发生了极小概率的哈希碰撞情况。
Object类中有对hashCode方法的定义,其他类都默认继承了这个方法。
2、待解决的问题:
HashSet集合对象中不允许添加重复数据。但对于两个对象cat1和cat2而言,即使它们的属性值一样,只要引用地址不一样,依旧会被视作不同对象,从而皆能被添加进相应的HashSet集合中。这不是我们想要的。
3、解决办法:
1)第一步:
只有重写Cat类中的equals方法,改变Cat类对 其实例化对象是否相等 的定义,才能解决这个问题。
2)第二步:
另外,重写Cat类中的equals方法时,也必须重写hashCode方法。
因为集合类为了提高“比较两个对象是否相同”的效率,首先会比较两个对象的hashCode值,如果两个对象的hashCode值不相等,则直接认定为两个对象不相等,后续不会再调用Cat类的equals方法进行“两个对象是否相同”的比较;如果两个对象的hashCode值相等,为避免是拥有不同属性值的对象发生了哈希碰撞而导致的hashCode值相等,在后续会继续调用Cat类对象的equals方法判断两个对象的各属性值是否也一样相等,如果也相等,则认定两个对象相同,否则认定两个对象不相同。
这一点在集合类的add方法中得到了直接体现,感兴趣的可以去看相关源码。另外,关于什么是哈希碰撞这里就不详述了,感兴趣的可以百度一下。
4、如果只重写了Cat类中的equals方法,而没有重写hashCode方法时的情况:
对于各属性值相等但引用地址不一样的两个对象cat1和cat2,HashSet集合对象的add方法在首先比较 两者不相等的hashCode值 以后,会直接认定cat1对象和cat2对象不相同,然后将两者皆添加到集合中。