1. Введите метод hashCode
-
hashCode()
Роль состоит в том, чтобы получить хэш-код, также известный как хэш-код, он фактически возвращает целое число. Роль этого хэш-кода заключается в определении позиции индекса объекта в хэш-таблице. -
hashCode()
Определено в JDK Object.java, что означает, что любой класс в Java содержитhashCode()
функции . -
Хеш-таблица хранит пары ключ-значение, и ее характеристика заключается в том, что соответствующее «значение» может быть быстро извлечено по «ключу». Здесь используются хэш-коды! (Вы сможете быстро найти нужный объект).
2. Зачем нужен метод hashCode?
В процессе написания программ определение, являются ли два объекта одинаковыми, является очень распространенной и часто встречающейся проблемой. hashCode()
Метод используется для повышения скорости сравнения двух объектов.
Давайте возьмем «Как HashSet проверяет наличие дубликатов» в качестве примера, чтобы проиллюстрировать, почему существует hashCode :
-
HashSet
Когда вы добавляете объект , HashSet сначала вычислитhashcode
значение объекта, чтобы определить, куда добавляется объект, а также сравнит его соhashcode
значениями совпадения нетhashcode
,HashSet
он будет считать, что объект не появляется повторно. -
Но если найдены объекты с одинаковым
hashcode
значением , то вызывается метод equals(), чтобы проверитьhashcode
, действительно ли равные объекты одинаковы. Если они совпадают,HashSet
операция соединения не будет успешной. Если он отличается, он будет перефразирован в другом месте. -
Таким образом, мы значительно уменьшаем
equals
количество раз и, соответственно, значительно улучшаем скорость выполнения.
3. Какая связь между методами hashCode() и equals()?
Java определяет метод equals() и метод hashCode() следующим образом:
- Несколько вызовов метода hashCode() для одного и того же объекта всегда возвращают одно и то же целочисленное значение.
- 如果 a.equals(b),则一定有 a.hashCode() 一定等于 b.hashCode()。
- 如果 !a.equals(b),则 a.hashCode() 不一定等于 b.hashCode()。此时如果 a.hashCode() 总是不等于 b.hashCode(),会提高 hashtables 的性能。
- a.hashCode()==b.hashCode() 则 a.equals(b) 可真可假
- a.hashCode()!= b.hashCode() 则 a.equals(b) 为假。
上面结论简记:
- 如果两个对象 equals,Java 运行时环境会认为他们的 hashCode 一定相等。
- 如果两个对象不 equals,他们的 hashCode 有可能相等。
- 如果两个对象 hashCode 相等,他们不一定 equals。
- 如果两个对象 hashCode 不相等,他们一定不 equals。
4、为什么重写 equals 方法必须重写 hashcode 方法 ?
-
我们上面讲解到 如果 两个对象
equals
的话,那么它们的hashCode
值必然相等。如果只重写了equals
方法,而不重写hashCode
的方法,会造成hashCode
的值不同,而equals
方法判断出来的结果为true
。 -
在Java中的一些容器中,不允许有两个完全相同的对象,插入的时候,如果判断相同则会进行覆盖。这时候如果只重写了
equals
的方法,而不重写hashCode
的方法,Object中hashCode
是根据对象的存储地址转换而形成的一个哈希值。这时候就有可能因为没有重写hashCode
方法,造成相同的对象散列到不同的位置而造成对象的不能覆盖的问题。
例如
Dog类
package com.xiao;
/**
* @author :小肖
* @date :Created in 2022/3/11 14:42
*/
public class Dog {
private String name;
private Integer age;
public Dog() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Dog(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()){
return false;
}
Dog dog = (Dog) obj;
if(dog.getAge() == age && dog.getName().equals(name)){
return true;
}
return false;
}
}
复制代码
测试类
import com.xiao.Dog;
public class Test {
public static void main(String[] args) {
Dog dog = new Dog("小旺",2);
Dog dog1 = new Dog("小旺",2);
System.out.println("equals结果:" + dog.equals(dog1));
System.out.println("dog 的 hashCode 值是否等于 dog1 的 hashCode 值:" +(dog.hashCode() == dog1.hashCode()));
}
}
复制代码
测试结果
equals结果:true
dog 的 hashCode 值是否等于 dog1 的 hashCode 值:false
复制代码