equals,即等价,用数学解释,等价关系拥有着自反、对称、传递三大性质,并不是简单的==。
我们判断两个对象是否等价,有两种方式,
1.观察等价性,即两个对象看起来相等。比如一个Person对象,有着name和address属性,若两个属性相同,则对象等价。
2.行为等价性,这里我理解为引用等价性,即两个引用指向一个内存对象。
hashcode()方法会返回对象的哈希值,哈希值姑且可以看作此对象的一个身份标识。
而java中的hashcode方法是基于equals方法的。若两个对象运用equals等价,那么它们必定hashcode相同。若equals方法重写,hashcode方法大概率也要重写。
而hashcode方法与equals方法为什么要保持一致性呢?看看下面这个例子:
public class User {
private long id;
private String name;
private String address;
private long phone;
//这里利用观察等价性重写equals方法
}//定义一个User类
这里定义了一个重写equals方法而没有重写hashcode方法的类,当执行下面的代码时:
HashMap<User, String> map = new HashMap<User,String>();
map.put(new User(100,"jack","beijing",10086),"yidong");
System.out.println(map.get(new User(100,"jack","beijing",10086)));
将不会输出yidong.
发生这样情况的原因在于:当第一次new User对象时,User对象依据引用的地址值生成hashcode,详细方法看参阅Object类的hashcode方法。
而第二次new User时,虽然 new了一个合乎equals标准的对象,但是由于没有重写hashcode方法,第二个对象的hashcode值与第一个不同,自然也就找不到map中的value值。
最后,不同的对象尽量要有不同的哈希值。
上图为哈希表的溢出表形式。若不同对象有着一样的哈希值,将都映射到一个区域,形成链表形式的溢出表。而对这些对象进行查找时,哈希表的效率会大大下降。
所以不同的对象有不同的哈希值会提高哈希表的效率。