Anular la función Hashcode en Java

Rupam Yadav 12 octubre 2023
  1. ¿Por qué anulamos el método hashcode()?
  2. Anular el método hashcode() en Java
Anular la función Hashcode en Java

hashcode en Java es una función que utiliza el algoritmo hash y devuelve un valor entero que representa un objeto. hashcode() es parte de la clase Object, lo que significa que esta función está disponible para todas las clases que heredan la clase Object.

Este artículo mostrará cómo podemos anular el método hashcode() para proporcionar nuestra implementación.

¿Por qué anulamos el método hashcode()?

Antes de proceder a anular la función hashcode(), debemos entender por qué necesitamos anular este método. Lo importante a tener en cuenta es que los métodos equals() y hashcode() van juntos y generalmente es obligatorio anular el método hashcode() cada vez que se anula la función equals(). Es porque ese hashcode() dice que si los objetos son iguales, sus códigos hash también deben ser iguales.

Para comprender prácticamente el motivo detrás de anular el método hashcode(), creamos un ejemplo con dos clases llamadas HashCodeExample y DummyClass. En DummyClass, proporcionamos un constructor simple que establece la variable abc. Ahora en la clase HashCodeExample, creamos dos instancias de la clase DummyClass y las nombramos como dummyClass1 y dummyclass2 con el mismo valor en sus constructores.

Comparamos las dos instancias usando el método equals(), pero el resultado muestra que no son iguales.

public class HashCodeExample {
  public static void main(String[] args) {
    DummyClass dummyClass1 = new DummyClass(10);
    DummyClass dummyClass2 = new DummyClass(10);

    System.out.println(dummyClass1.equals(dummyClass2));
  }
}

class DummyClass {
  int abc;

  public DummyClass(int abc) {
    this.abc = abc;
  }
}

Producción :

false

Ocurre porque cada instancia de objeto en Java recibe un código hash único que podemos verificar llamando al método hashCode() en ambos objetos. El resultado muestra que los valores enteros de ambos objetos son diferentes.

System.out.println(dummyClass1.hashCode());
System.out.println(dummyClass2.hashCode());

Producción :

2065951873
1791741888

Para solucionar el problema de los objetos desiguales, podemos anular la función equals() y usar nuestra implementación. El siguiente código es el mismo que el primer programa, pero anulamos el método equals() que toma un Object como argumento y devuelve un booleano.

En la función equals(), convertimos el parámetro o de tipo Object como el tipo de DummyClass que devuelve una instancia de DummyClass. Ahora comparamos la variable abc de la clase DummyClass con la variable del objeto abc que se pasa en el método como argumento.

El resultado muestra que el resultado de dummyClass1.equals(dummyClass2) es true porque modificamos la implementación predeterminada para que devuelva verdadero si los valores de las instancias son los mismos.

public class HashCodeExample {
  public static void main(String[] args) {
    DummyClass dummyClass1 = new DummyClass(10);
    DummyClass dummyClass2 = new DummyClass(10);

    System.out.println(dummyClass1.equals(dummyClass2));
  }
}

class DummyClass {
  int abc;

  public DummyClass(int abc) {
    this.abc = abc;
  }

  @Override
  public boolean equals(Object o) {
    DummyClass dummyClassObj = (DummyClass) o;
    return this.abc == dummyClassObj.abc;
  }
}

Producción :

true

La solución anterior solo funciona cuando comparamos los valores y no los códigos hash porque los códigos hash de los objetos dummyClass1 y dummyClass2 siguen siendo diferentes.

Para ilustrarlo mejor, creamos un HashSet() que devuelve un objeto de tipo Set<DummyClass> y le agregamos ambos objetos DummyClass usando la función add(). Ahora imprimimos el Set y obtenemos dos objetos con diferentes referencias en la salida, lo que prueba que los objetos DummyClass tienen diferentes códigos hash.

Aquí es donde anulamos la función hashcode() para solucionar el problema, que veremos en el siguiente ejemplo a continuación.

import java.util.HashSet;
import java.util.Set;

public class HashCodeExample {
  public static void main(String[] args) {
    DummyClass dummyClass1 = new DummyClass(10);
    DummyClass dummyClass2 = new DummyClass(10);

    Set<DummyClass> dummyClassSet = new HashSet<>();
    dummyClassSet.add(dummyClass1);
    dummyClassSet.add(dummyClass2);
    System.out.println(dummyClassSet);
  }
}

class DummyClass {
  int abc;

  public DummyClass(int abc) {
    this.abc = abc;
  }

  @Override
  public boolean equals(Object o) {
    DummyClass dummyClass = (DummyClass) o;
    return this.abc == dummyClass.abc;
  }
}

Producción :

[DummyClass@7b23ec81, DummyClass@6acbcfc0]

Anular el método hashcode() en Java

Para usar nuestra implementación en el método hashcode(), primero anulamos el método hashcode() en la clase DummyClass y devolvemos el valor de la variable de clase abc. Ahora el código hash se reemplaza con el valor de abc. Ahora, si imprimimos dummyClassSet, obtenemos solo un objeto porque el código hash o la referencia es el mismo.

import java.util.HashSet;
import java.util.Set;

public class HashCodeExample {
  public static void main(String[] args) {
    DummyClass dummyClass1 = new DummyClass(10);
    DummyClass dummyClass2 = new DummyClass(10);

    Set<DummyClass> dummyClassSet = new HashSet<>();
    dummyClassSet.add(dummyClass1);
    dummyClassSet.add(dummyClass2);

    System.out.println(dummyClassSet);
  }
}

class DummyClass {
  int abc;

  public DummyClass(int abc) {
    this.abc = abc;
  }

  @Override
  public boolean equals(Object o) {
    DummyClass dummyClass = (DummyClass) o;
    return this.abc == dummyClass.abc;
  }

  @Override
  public int hashCode() {
    return abc;
  }
}

Producción :

[DummyClass@a]

Si imprimimos los códigos hash de los objetos dummyClass1 y dummyClass2, obtenemos los mismos códigos hash.

System.out.println(dummyClass1.hashCode());
System.out.println(dummyClass2.hashCode());

Producción :

10
10
Rupam Yadav avatar Rupam Yadav avatar

Rupam Saini is an android developer, who also works sometimes as a web developer., He likes to read books and write about various things.

LinkedIn