La anulación del método hashCode() está estrechamente relacionada con la anulación de equals(): ambos métodos forman la base para el uso correcto de un objeto en colecciones como HashMap, HashSet, Hashtable y otras estructuras que se basan en comparaciones y funciones hash.
Reglas:
equals(), asegúrate de anular también hashCode().equals() deben devolver el mismo hashCode().Objects.hash() o plantillas de IDE, para evitar errores.hashCode() debe devolver el mismo valor para el mismo objeto durante su "vida" (si los campos que participan en hashCode son inmutables).class User { private String name; public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof User)) return false; User user = (User) o; return Objects.equals(name, user.name); } public int hashCode() { return Objects.hash(name); } }
Pregunta: "¿Qué sucede si dos objetos diferentes según equals() devuelven el mismo hashCode()? ¿Esto será un error?"
Respuesta: No, esto no es un error. Las colisiones de códigos hash son manejables y esperadas; solo es importante que si los objetos son iguales según equals, su hashCode sea el mismo. Si los objetos diferentes según equals dan el mismo hashCode, las colecciones funcionarán más lentamente (debido a un mayor número de colisiones), pero de manera correcta.
Historia
En un software financiero, se comparaban proyectos por varios campos, pero solo se anuló equals(). Se almacenaron objetos en HashSet, ocurrieron duplicados, ya que hashCode() no se había anulado y funcionaba por defecto (diferente para cada instancia).
Historia
En un sistema de gestión de inventarios, después de agregar cambios en la lógica de negocio, se amplió equals(), pero se olvidó de actualizar hashCode(). Objetos con hashCode diferentes, pero equals=true, se perdieron en HashMap (no se encontraban por clave), lo que llevó a grandes errores financieros.
Historia
En una aplicación web, se utilizaron campos mutables en el cálculo de hashCode. Al actualizar el valor de un campo interno, el hash cambiaba y el objeto "se perdía" para HashSet/HashMap: no podía ser encontrado o eliminado a través de métodos estándar, lo que conducía a fugas de memoria y errores.