根据Object规范,规范约定:
- 如果两个对象通过equals方法比较是相等的,那么它们的hashCode方法结果值也是相等的。
- 如果两个对象通过equals方法比较是不相等的,那么不要求它们的hashCode方法结果值是相等的。
- 当在一个应用程序执行过程中, 如果equals方法比较中没有修改任何信息,那么在同一个对象上重复调用hashCode方法时,它必须始终返回相同的值。但如果从一个应用程序到了另一个应用程序,两个应用程序汇中调用hashCode方法的返回值可以是不一致的。
Object类中的默认的equals和hashCode方法:
- equals:比较的是对象的内存地址是否相同(相当于==操作符);
- hashCode:hashCode方法的返回值符合上述规范。
public boolean equals(Object obj) {
return (this == obj);
}
public native int hashCode();
所以:
1、为了保证一个原则,equals相同的两个对象hashcode必须相同。如果重写了equals而没有重写hashcode,会出现equals相同hashcode不相同这个现象。
2、在散列集合中,是使用hashcode来计算key应存储在hash表的索引,如果重写了equals而没有重写hashcode,会出现两个完全相同的两个对象,hashcode不同,计算出的索引不同,那么这些集合就乱套了。
3、提高效率,当我们比较两个对象是否相同的时候,先比较hashcode是否相同,如果hashcode不相同肯定不是一个对象,如果hashcode相同再调用equals来进行比较,减少比较次数提高效率。
重写后两个方法的关系:
equals()相等的两个对象,hashcode()一定相等;
hashcode()不等,一定能推出equals()也不等;
hashcode()相等,equals()可能相等,也可能不等。
所以先进行hashcode()判断,不等就不用equals()方法了。
但equels是是根据对象的特征进行重写的,有时候特征相同,但hash值不同,也不是一个对象。 所以两个都重写才能保障是同一个对象。