38
votes

I am converting the incoming string into hash code by doing the following function but some of the values are negative. I don't think hash values should be negative. Please tell me what I am doing wrong.

int combine = (srcadd + dstadd + sourceport + destinationport + protocol).hashCode();
System.out.println(combine);
3
Why can't hash codes be negative? AFAIK, the only requirement to them is to be equal for equal objects..user1096188

3 Answers

58
votes

I don't think hash values should be negative.

Why not? It's entirely valid to have negative hash codes. Most ways of coming up with a hash code naturally end up with negative values, and anything dealing with them should take account of this. However, I'd consider a different approach to coming up with your hash codes, e.g.

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;

It's not clear what the types of these expressions are, but I'm guessing you're ending up taking the hash code of a string... a string that you don't really need to create in the first place. While there are better approaches for getting hash codes for known domains, the above approach works well as a general-purpose hash generation technique.

Note that it would also help the readability of your code if you avoided abbreviations, and used camel casing, e.g. sourceAddress instead of srcadd.

40
votes

sometimes the hashcode calculation itself goes beyond the Integer.MAX_VALUE, i.e 2147483647. what happens then is that we get a negative integer after the overflow. Negative hashcode is perfectly valid!

23
votes

It is perfectly legal to have negative hash codes, and if you are looking for hash values as used in hash-based collections you can use Math.abs(hash). This can also give you negative numbers when hash is bigger than 2^31, and the best way would be to use a shift mask (key.hashCode() & 0x7fffffff) % M, where M is the table size.