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()