¿Para qué sirve hashCode en Java?

Respuestas:

222

hashCode()se utiliza para bucketing en Hashimplementaciones gustaría HashMap, HashTable, HashSet, etc.

El valor recibido de hashCode()se utiliza como número de depósito para almacenar elementos del conjunto / mapa. Este número de depósito es la dirección del elemento dentro del conjunto / mapa.

Cuando lo haga contains(), tomará el código hash del elemento y luego buscará el depósito al que apunta el código hash. Si se encuentra más de 1 elemento en el mismo depósito (varios objetos pueden tener el mismo código hash), entonces utiliza el equals()método para evaluar si los objetos son iguales y luego decidir si contains()es verdadero o falso, o decidir si el elemento podría ser agregado en el conjunto o no.

aish
fuente
28
Hola amigo ... Muy buena respuesta, pero encontré un enlace muy interesante para el mismo con un ejemplo práctico fácil de entender: coderanch.com/t/321515/java/java/HashCode
Logicalj
Gracias aishu. Ahora tengo un conocimiento claro sobre el código hash con una explicación relacionada con el cubo.
Balasubramani
2
"si se encuentra más de 1 elemento en el mismo depósito ... entonces usa el equals()para evaluar", entonces, ¿qué sucede si solo se encuentra un elemento coincidente de código hash, devuelve verdadero directamente? pero dado que varios objetos pueden tener el mismo código hash, por lo que debe ejecutarse equals()para evaluar si el elemento coincidente es igual, de lo contrario, puede obtener un resultado inesperado, ¿estoy en lo cierto?
Saorikido
A un lado, el código hash es un método que el objeto llama para determinar el orden para almacenar cada objeto en la memoria. Si los objetos son iguales, entonces su código hash también debe ser igual. (lo contrario de esta declaración es falso)
NoName
1
¿En qué caso un programador invocaría manualmente el hashCode()método?
Cardenal - Restablece a Mónica el
33

Del Javadoc :

Devuelve un valor de código hash para el objeto. Este método es compatible con el beneficio de tablas hash como las proporcionadas por java.util.Hashtable.

El contrato general de hashCodees:

  • Cada vez que se invoca en el mismo objeto más de una vez durante la ejecución de una aplicación Java, el hashCodemétodo debe devolver consistentemente el mismo número entero , siempre que no se modifique la información utilizada en comparaciones iguales en el objeto. Este entero no necesita permanecer consistente de una ejecución de una aplicación a otra ejecución de la misma aplicación.

  • Si dos objetos son iguales según el equals(Object)método, entonces llamar al hashCodemétodo en cada uno de los dos objetos debe producir el mismo resultado entero.

  • Se no requiere que si dos objetos son desiguales de acuerdo con el equals(java.lang.Object)método, entonces llama a la hashCodemétodo en cada uno de los dos objetos debe producir resultados enteros distintos. Sin embargo, el programador debe ser consciente de que producir resultados enteros distintos para objetos desiguales puede mejorar el rendimiento de las tablas hash.

Por mucho que sea razonablemente práctico, el método hashCode definido por la clase Object devuelve enteros distintos para objetos distintos. (Esto generalmente se implementa convirtiendo la dirección interna del objeto en un número entero , pero el lenguaje de programación Java no requiere esta técnica de implementación).

John Topley
fuente
14

El valor devuelto por hashCode() es el código hash del objeto, que es la dirección de memoria del objeto en hexadecimal.

Por definición, si dos objetos son iguales, su código hash también debe ser igual. Si anula el equals()método, cambia la forma en que se igualan dos objetos y la implementación de Object hashCode()ya no es válida. Por lo tanto, si anula el método equals (), también debe anular el hashCode()método.

Esta respuesta es de la documentación del tutorial oficial de Java SE 8

Eli
fuente
13

hashCode()es una función que toma un objeto y genera un valor numérico. El código hash para un objeto es siempre el mismo si el objeto no cambia.

Funciones como HashMap, HashTable, HashSet, etc. que necesidad de objetos de almacén va a utilizar un hashCodemódulo el tamaño de su matriz interna para elegir en lo que "posición de memoria" (es decir, posición de matriz) para almacenar el objeto.

Hay algunos casos en los que pueden ocurrir colisiones (dos objetos terminan con el mismo código hash), y eso, por supuesto, debe resolverse con cuidado.

roottraveller
fuente
6

Aunque el código hash no hace nada con la lógica de su negocio, tenemos que cuidarlo en la mayoría de los casos. Porque cuando su objeto se coloca en un contenedor basado en hash (HashSet, HashMap ...), el contenedor coloca / obtiene el código hash del elemento.

卢 声 远 Shengyuan Lu
fuente
No, no lo hace. Pone / obtiene la llave. El hashCode solo se usa para bucketing,
Marqués de Lorne
3

Un código hash es un número generado a partir de cualquier objeto.

Esto es lo que permite que los objetos se almacenen / recuperen rápidamente en una tabla hash.

Imagine el siguiente ejemplo simple :

En la mesa frente a ti. tiene nueve cajas, cada una marcada con un número del 1 al 9. También tiene una pila de objetos muy diferentes para almacenar en estas cajas, pero una vez que estén allí, debe poder encontrarlos lo más rápido posible.

Lo que necesita es una forma de decidir instantáneamente en qué cuadro ha colocado cada objeto. Funciona como un índice. decide buscar el repollo para buscar en qué caja está el repollo y luego ir directamente a ese recuadro para obtenerlo.

Ahora imagine que no quiere molestarse con el índice, desea poder averiguar inmediatamente desde el objeto en qué caja vive.

En el ejemplo, usemos una forma realmente simple de hacer esto: la cantidad de letras en el nombre del objeto. Entonces el repollo entra en la caja 7, el guisante entra en la caja 3, el cohete en la caja 6, el banjo en la caja 5 y así sucesivamente.

Sin embargo, ¿qué pasa con el rinoceronte? Tiene 10 caracteres, por lo que cambiaremos un poco nuestro algoritmo y lo "envolveremos" para que los objetos de 10 letras entren en el cuadro 1, 11 letras en el cuadro 2 y así sucesivamente. Eso debería cubrir cualquier objeto.

A veces, una caja tendrá más de un objeto, pero si está buscando un cohete, aún es mucho más rápido comparar un maní y un cohete que verificar un montón de coles, guisantes, banjos y rinocerontes.

Ese es un código hash. Una forma de obtener un número de un objeto para que pueda almacenarse en una tabla hash. En Java, un código hash puede ser cualquier número entero, y cada tipo de objeto es responsable de generar el suyo. Busque el método "hashCode" de Object.

Fuente - aquí

Satyajit Das
fuente
-1

Uno de los usos de hashCode () es construir un mecanismo de captura . Mira este ejemplo:

        class Point
    {
      public int x, y;

      public Point(int x, int y)
      {
        this.x = x;
        this.y = y;
      }

      @Override
      public boolean equals(Object o)
      {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Point point = (Point) o;

        if (x != point.x) return false;
        return y == point.y;
      }

      @Override
      public int hashCode()
      {
        int result = x;
        result = 31 * result + y;
        return result;
      }

class Line
{
  public Point start, end;

  public Line(Point start, Point end)
  {
    this.start = start;
    this.end = end;
  }

  @Override
  public boolean equals(Object o)
  {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Line line = (Line) o;

    if (!start.equals(line.start)) return false;
    return end.equals(line.end);
  }

  @Override
  public int hashCode()
  {
    int result = start.hashCode();
    result = 31 * result + end.hashCode();
    return result;
  }
}
class LineToPointAdapter implements Iterable<Point>
{
  private static int count = 0;
  private static Map<Integer, List<Point>> cache = new HashMap<>();
  private int hash;

  public LineToPointAdapter(Line line)
  {
    hash = line.hashCode();
    if (cache.get(hash) != null) return; // we already have it

    System.out.println(
      String.format("%d: Generating points for line [%d,%d]-[%d,%d] (no caching)",
        ++count, line.start.x, line.start.y, line.end.x, line.end.y));
}
Sudabe-Neirizi
fuente
¿Qué significa 'construir un mecanismo de captura'? ¿Y cómo lo ilustra este código?
Marqués de Lorne
-1

hashCode()es un unico código generado por la JVM para cada creación de objeto.

Utilizamos hashCode()para realizar algunas operaciones en algoritmos relacionados con hash como Hashtable, Hashmap, etc.

Las ventajas de hashCode()facilitar la operación de búsqueda porque cuando buscamos un objeto que tiene un código único, ayuda a descubrir ese objeto.

Pero no podemos decir hashCode()es la dirección de un objeto. Es un código único generado por JVM para cada objeto.

Es por eso que hoy en día el algoritmo de hashing es el algoritmo de búsqueda más popular.

Sahu pritish
fuente
44
Hashcode no es único. 2 objetos desiguales pueden devolver el mismo código hash.
Ranielle Canlas