1. Introducir el método hashCode
-
hashCode()
La función de es obtener el código hash, también conocido como código hash, en realidad devuelve un entero int. La función de este código hash es determinar la posición de índice del objeto en la tabla hash. -
hashCode()
Definido en Object.java de JDK, lo que significa que cualquier clase en Java contienehashCode()
funciones . -
La tabla hash almacena pares clave-valor, y su característica es que el "valor" correspondiente se puede recuperar rápidamente de acuerdo con la "clave". ¡Aquí es donde se usan los códigos hash! (Puede encontrar rápidamente el objeto deseado).
2. ¿Por qué necesita el método hashCode?
En el proceso de escribir programas, determinar si dos objetos son iguales es un problema muy común y frecuente. El hashCode()
método se utiliza para mejorar la velocidad de comparación de dos objetos.
Tomemos como ejemplo "Cómo HashSet verifica si hay duplicados" para ilustrar por qué hay un hashCode :
-
HashSet
Cuando agrega un objeto , HashSet primero calculará elhashcode
valor del objeto para determinar dónde se agrega el objeto y también lo comparará con loshashcode
valores . Si no hay coincidenciahashcode
,HashSet
asumirá que el objeto no aparece repetidamente. -
Pero si se encuentran objetos con el mismo
hashcode
valor , se llama al método equals() para verificarhashcode
si los objetos iguales son realmente iguales. Si los dos son iguales,HashSet
la operación de combinación no tendrá éxito. Si es diferente, se repetirá en otro lugar. -
De esta manera, reducimos mucho el número
equals
de veces y, en consecuencia, mejoramos mucho la velocidad de ejecución.
3. ¿Cuál es la relación entre los métodos hashCode() y equals()?
Java define el método equals() y el método hashCode() de la siguiente manera:
- Varias llamadas al método hashCode() en el mismo objeto siempre devuelven el mismo valor entero.
- 如果 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
复制代码