这个问题也可以变成:为什么两个对象的equals不等,但他们的HashCode相等?为什么重写equals方法时必须重写HashCode()?
网络上有很多用map存对象来解释这个问题,其实也很好理解:利用HashCode和equals可以使map保持唯一性的计算量大大降低
那么为什么对比了HashCode了之后却仍然不能确定他们相等呢?
这里先提什么是HashCode:简单一点就是每一个对象都有他们实际存在的物理地址,将物理地址转换成一个整数,然后通过哈希算法将整数转换成的东西(32位散列码)就是HashCode,所以
如果哈希表中的一个位置对应了多个对象,那么它们的HashCode就是相同的。
例如Hash表有5个位置对应1,2,3,4,5,但要存100个数,每个位置可能就要存20个数,当第101个数来的时候,它要存在第1个位置,那么我只需要对比(equals)和它HashCode相同的(也就是都存在第一个位置的)20个数的其它条件就行,就不需要对比100个数那么麻烦。实际中Hash表可能会很大,对比的次数可能比20次要小得多。实际上Hash表是足够大的,一个数、字符串或者对象的存储远低于20次(hashCode返回独一无二的散列码,会让存储这个对象的hashtables更好地工作)
Java官方对于equals和HashCode这一声明:
1、如果两个对象相同,那么它们的hashCode值一定要相同;2、如果两个对象的hashCode相同,它们并不一定相同,上面说的对象相同指的是用eqauls方法比较。
所以,我们在手动重写equals方法时,最好将对比HashCode 的条件加上。如果不这样的话,使用map存东西时的效率会大幅下降。
Ps:
1.HashCode是一个native方法,根据官方文档来说:"A native method is a Java method whose
implementation is provided by non-java code.",native方法由非java语言实现。
2.String类中的equals首先比较地址,如果是同一个对象的引用,可知对象相等,返回true。若果不是同一个对象,equals方法挨个比较两个字符串对象内的字符,只有完全相等才返回true,否则返回false。