今天跟同事讨论到一些java基础的问题:
1、什么时候重写equals?
2、什么时候重写hashcode?
3、什么时候两个都要重写?
4、equals相等hashcode一定相等吗?
5、hashcode相等equals一定相等吗?
现在,对这几个问题,好好做一下分析:
第一:什么时候需要重写equals
首先,对于equals,我要知道它自己有一套比较的逻辑,对于非引用对象,它比较的是对象本身的值。对于引用对象,它比较的是对象的引用地址。所以,如果这种原始的判断对象是否相同的逻辑不满足需要,这时候就需要重写equals方法。
第二:什么时候需要重写hashCode
在JDK中我们知道,对hashCode的协定:在对同一对象进行多次的调用hashCode方法是,必须要返回相同的整数,前提是将对象进行equals比较时所有的信息没有被修改。同时,如果两个对象是相等的,那么这两个对象中hashCode也必须是相同的。因为hashCode()方法和equals()方法是伴生的。所以,在重写了equals()方式,也同时要重写hashCode()方法。
当然,这只是一种协定。那如果说我重写了equals()之后就是不重写hashCode(),那会有什么影响呢?可以举一个简单的例子,对于集合Set,我们都知道它的特点:无序,元素不可重复。我们定义一个对象User,重写了它的equals()方法,没有重写hashCode()方法,然后声明两个对象放入Set中,我们会发现,equals()返回true表示是相同的对象,但是两个对象却又都能放入Set中。这是因为在Set中,是先根据对象的hashCode来获取要存储的物理地址,如果改地址空间没有元素,就直接保存不在继续比较。我们因为没有重写User对象的hashCode()方法,声明的两个对象的hashCode是不同的。
当然如果你说不把对象放入集合中,那么仅仅是用来判断两个对象是否相等,也能达到效果。
第三:什么时候两个都要重写
如果重写了equals()方法之后,也要重写hashCode()方法
第四:equals相等hashCode一定相等么
对这个问题,我只能说如果都按照jdk协定来做,那如果equals相等,hashCode必然相等
第五:hashCode相等equals一定相等么
hashCode相等,equals不一定相等。因为hashCode是根据某种算法来实现的,所以有可能在存在两个对象equals不等而hashCode相等的情况
所以,总结一下,如果遵循协议:
1、equals相等的时候,hashCode也一定相等
2、如果hashCode相等,equals不一定相等
3、equals不等,hashCode可能相等