Si hashCode() está mal hecho …
Si hashCode()
devuelve valores diferentes para objetos que son equivalentes, según equals(),
las clases del tipo HashMap y HashSet fallan.
Si hashCode()
devuelve valores que, aún estando correctos, no discriminan entre objetos que
no son equivalentes, las clases HashMap y HashSet se ralentizan.
Como ejemplo
extremo,
int hashCode(){ return 0; }
es código correcto,
pero extremadamente ineficiente.
Sea
public class Cadena {
private String texto;
private static Random random = new
Random();
public Cadena(String texto) {
this.texto = texto;
}
@Override
public boolean equals(Object x) {
if (x == this) return true;
if (x == null) return false;
if (!(x instanceof Cadena)) return
false;
Cadena otro = (Cadena) x;
return texto.equals(otro.texto);
}
@Override
public int hashCode() {
return texto.hashCode();
}
public static void main(String[] args) {
Set<Cadena> set = new
HashSet<Cadena>();
long t0 = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
Cadena ejemplo = new Cadena(getAlgo());
set.add(ejemplo);
if (set.contains(ejemplo) == false)
System.out.println("falla");
}
long t2 = System.currentTimeMillis();
System.out.printf("%dms%n",
t2 - t0);
}
private static String getAlgo() {
return Long.toString(random.nextLong(),
36);
}
}
Si ejecutamos,
obtenemos un tiempo de ejecución de
46ms
Si cambiamos a
int hashCode(){ return 0; }
el tiempo de
ejecución pasa a
1307ms
Como moraleja
podemos decir que si va a redefinir el método hashCode() de una clase, es buena
idea hacer algunos experimentos de eficiencia para elegir una función que,
siendo correcta, no penalice la ejecución. No hay recetas mágicas; pero los
patrones indicados en las secciones anteriores suelen funcionar razonablemente
bien.
Temas relacionados
86. hashCode (método) public int hashCode()