I have an
HashMap<String,AnObject>
and I'd like to give the string key a value from some infos the AnObject value contains. Suppose AnObject is made this way:
public class AnObject(){
public String name;
public String surname;
}
Is it correct to assign the key to:
String.valueOf(o.name.hashcode()+o.surname.hashcode());
? Or Is there a better way to compute a String hash code from a value list?
No, absolutely not. hashCode()
is not guaranteed to be unique.
The rules of a hash code are simple:
hashCode()
, but more than 232 possible strings, making uniqueness impossible.Hash codes are an optimization technique to make it quick to find a "probably small" set of candidate values equal to some target, which you then iterate through with a rigorous equality check to find whether any of them is actually equal to the target. That's what lets you quickly look something up by key in a hash-based collection. The key isn't the hash itself.
If you need to create a key from two strings, you're going to basically have to make it from those two strings (with some sort of delimiter so you can tell the difference between {"a", "bc"} and {"ab", "c"} - understanding that the delimiter itself might appear in the values if you're not careful).
See Eric Lippert's blog post on the topic for more information; that's based on .NET rather than Java, but they all apply. It's also worth understanding that the semantics of hashCode
aren't necessarily the same as those of a cryptographic hash. In particular, it's fine for the result of hashCode()
to change if you start a new JVM but create an object with the same fields - no-one should be persisting the results of hashCode
. That's not the case with something like SHA-256, which should be permanently stable for a particular set of data.
See more on this question at Stackoverflow