Estoy leyendo el código de la clase HashMap que proporciona la API Java 1.6 y es incapaz de comprender plenamente la necesidad de la operación siguiente (que se encuentran en el cuerpo de PUT y GET métodos):¿Por qué un HashMap repite el código hash proporcionado por el objeto clave?
int hash = hash(key.hashCode());
donde el método hash()
tiene el siguiente cuerpo:
private static int hash(int h) {
h ^= (h >>> 20)^(h >>> 12);
return h^(h >>> 7)^(h >>> 4);
}
Esto vuelve a calcular el hash de manera efectiva mediante la ejecución de operaciones de bits en el código hash suministrado. Soy incapaz de comprender la necesidad de hacerlo a pesar de que la API establece de la siguiente manera:
Esto es crítico porque HashMap utiliza tablas de hash longitud de energía-de-dos, que de otra manera se encuentran con colisiones para que hashcodes no difiera en bits inferiores.
Entiendo que los pares de valores clave se almacenan en una matriz de estructuras de datos, y que la ubicación del índice de un elemento en esta matriz está determinada por su hash. Lo que no entiendo es cómo agregaría esta función ningún valor a la distribución hash.
"por las dudas" ? En realidad, la mayoría de los códigos hash en Java van a estar mal. ¡Solo mira java.lang.Integer, por ejemplo! Pero esto realmente tiene sentido. Es mejor decir "está bien si Object.hashCode() s de todos tiene una distribución de bits desatinada, siempre y cuando sigan la regla de igualdad de objetos con códigos hash, y trate de evitar las colisiones tanto como sea posible". Entonces, solo las implementaciones de recolección como HashMap tienen la carga de pasar esos valores a través de una función secundaria de hash, en lugar de ser un problema de todos. –
'las posiciones impares del hashmap nunca se usarían' No lo entiendo. ¿Puedes dar un ejemplo? –
Ok, imagina que estoy haciendo hash Objetos de empleado, y todos mis empleados tienen un campo de Id. Int. Como "400114", "400214", "400314", etc. (todos comparten la parte "14" de sus ID porque eso es el sufijo de mi departamento). El método hashCode() de Integer devuelve el entero en sí, así que si tuviera que usar los ID de los empleados como claves en un hash HashSet/sin/HashMap (int h), el spread sería muy, muy desigual. En este ejemplo, dado que 14 es par, solo se usarán incluso cubos. – tucuxi