I remember eclipse and idea have this template to automatically create an object's hashCode based on its attributes.
One of the strategies if a number and a string is used is something like this.
return stringValue.hashCode() + intValue * 32;
Ooor something like that.
I don't have nor eclipse or idea at hand and I would like to create such function.
EDIT
Based on the answers I create this mini-class
class StringInt {
private final String s;
private final int i;
static StringInt valueOf( String string , int value ) {
return new StringInt( string, value );
}
private StringInt( String string, int value ) {
this.s = string;
this.i = value;
}
public boolean equals( Object o ) {
if( o != null && o instanceof StringInt ){
StringInt other = ( StringInt ) o;
return this.s == other.s && this.i == other.i;
}
return false;
}
public int hashCode() {
return s != null ? s.hashCode() * 37 + i : i;
}
}
This class is to be used as key for a large memory map ( > 10k elements ) I don't want to iterate them each time to find if the String and the int are the same.
Thank you.
ps.. mmh probably it should be names StringIntKey.
Or, if you don't want to add another library, do something like the following:
You can also use
Objects
class fromjava.util.Objects
package to quickly get hash code.Use the Apache Commons HashcodeBuilder:
Link here: http://commons.apache.org/lang/api-2.3/org/apache/commons/lang/builder/HashCodeBuilder.html
And here:
http://www.koders.com/java/fidCE4E86F23847AE93909CE105394B668DDB0F491A.aspx
Eclipse always does roughly the same hashing function, here's an example for a class with an in and String as fields
They always pick 31 as the prime, and then multiple by build in hash functions or the value if its a primitive. Something like this wouldn't be hard to create as a method.
Further to your most recent edit, if retrieval speed is more important than storage concerns you could pre-compute and store the hash code when constructing your
StringInt
class. This is safe as you've marked theString
andint
fields asfinal
, and also given thatString
is immutable.Also, you could optimise your
equals
method by checking that the object being compared ==this
before doing a full comparison. I would also recommend doing the cheaper int-based comparison first before comparing the string fields.Another final suggestion: You could change your
valueOf(String, int)
method to either construct aStringInt
or return a previously created instance if one already exists with the sameString
and int values. This makes construction more expensive but comparisons very cheap as you can compareStringInt
s using "==" in the knowledge that no twoStringInt
s will ever be created with the sameString
andint
value.A hashcode method is something that potentially be called many times, and is therefore worth optimizing. If the calculation is complicated, consider memoizing the hash value. Also, avoid doing things that entail more calculation than is necessary. (For example, the StringBuilder solution spends most of its time creating the temporary String.)
The other thing I want to point out is that the quality of the hash is important. You want to avoid any hashcode algorithm that maps lots of common keys. If that happens, hash table lookup may no longer be O(1). (In the worst case it will be O(N) ... i.e. equivalent to a linear search!). Here's an example of a bad hash function:
Consider what happens if an element of
this.values
is zero ...