2012-02-12 22 views
21

Estoy convirtiendo la cadena entrante en código hash haciendo la siguiente función, pero algunos de los valores son negativos. No creo que los valores de hash sean negativos. Por favor dime que estoy haciendo mal.HashCode dando valores negativos

int combine = (srcadd + dstadd + sourceport + destinationport + protocol).hashCode(); 
System.out.println(combine); 
+5

¿Por qué los códigos hash no son negativos? AFAIK, el único requisito para ellos es ser iguales para objetos iguales. Los espacios – user1096188

+5

son agradables. – AHungerArtist

Respuesta

35

No creo que los valores hash debe ser negativo.

¿Por qué no? Es completamente válido tener códigos hash negativos. La mayoría de las formas de llegar a un código hash, naturalmente, terminan con valores negativos, y todo lo relacionado con ellos debe tener esto en cuenta. Sin embargo, consideraría un enfoque diferente para crear sus códigos hash, p.

int hash = 17; 
hash = hash * 31 + srcadd.hashCode(); 
hash = hash * 31 + dstadd.hashCode(); 
hash = hash * 31 + sourceport; // I'm assuming this is an int... 
hash = hash * 31 + destinationport; // ditto 
hash = hash * 31 + protocol.hashCode(); 
return hash; 

No está claro cuáles son los tipos de estas expresiones son, pero supongo que está terminando de tomar el código hash de una cadena ... una cadena que usted realmente no necesita crear en El primer lugar. Si bien hay mejores enfoques para obtener códigos hash para dominios conocidos, el enfoque anterior funciona bien como una técnica de generación de hash de propósito general.

Tenga en cuenta que también ayudaría a la legibilidad de su código si evitó las abreviaturas y utilizó la carcasa de camello, p. sourceAddress en lugar de srcadd.

+1

En realidad, se escribió en algún foro que "hashCode es una forma de calcular una pequeña clave numérica de resumen (32 bits) de una cadena larga". Entonces, creo que su rango es 2^32 y eso es de 0 a 2^32 – Xara

+3

@Zara: Pero 'int' no admite números mayores que 2^31 - 1 ... it * es * un valor de 32 bits, pero en un rango con signo. –

17

a veces el cálculo de hashcode va más allá del Integer.MAX_VALUE, es decir, 2147483647. lo que sucede entonces es que obtenemos un entero negativo después del overflow. ¡El hashcode negativo es perfectamente válido!

10

es perfectamente legal tener códigos hash negativos, y si usted está buscando los valores de troceo tal como se utiliza en colecciones basado en hash se pueden utilizar Math.abs(hash). Esto también puede dar números negativos cuando hash es mayor que 2^31, y la mejor manera sería usar una máscara de cambio (key.hashCode() & 0x7fffffff) % M, donde M es el tamaño de la tabla.

+1

No entiendo por qué no usaría Math.abs (hash). Entiendo que Math.abs() solo devolverá negativo para int.MIN_VALUE. Si hash = key.hashCode()% M, entonces la única forma de terminar con hash == int.MIN_VALUE es si M> int.MAX_VALUE, en cuyo caso necesitarías usar longs para indexar la tabla de todos modos. – jkindwall

+0

Por "más grande que 2^31", esta respuesta realmente significa "más de 31 dígitos binarios", no un entero * mayor que 2^31. ¿Por qué '(key.hashCode() & 0x7fffffff)'? Porque es una simple operación binaria de 1 paso sobre el resultado de 'hashCode()' que debería (o podría) ejecutarse más rápido que 'Math.abs()'. –

-1

Puede usar Math.abs(hash) para crear un valor positivo desde hashcode negativo.

Cuestiones relacionadas