Create hash from string and int

22,742

Solution 1

Use the Apache Commons HashcodeBuilder:

public int hashCode() {
    new HashCodeBuilder(17, 37).
           append(myString).
           append(myInt);
}

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

Solution 2

You can also use Objects class from java.util.Objects package to quickly get hash code.

@Override
public int hashCode() {
    return Objects.hash(this.string, this.integerValue, this.otherDataTypes);
}

Solution 3

Eclipse always does roughly the same hashing function, here's an example for a class with an in and String as fields

    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + this.interger;
        result = prime * result + ((this.string == null) ? 0 : this.string.hashCode());
        return result;
    }

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.

     public int hashCode(Object ... things) {
         final int prime = 31;
         int result = 1;
         for(Object thing : things) {
             result = prime * result + thing.hashCode();
         }
         return result;
     }

Solution 4

Or, if you don't want to add another library, do something like the following:

public int hashCode() {
    StringBuilder builder = new StringBuilder();
    builder.append(myString);
    builder.append(myInteger);
    return builder.toString().hashCode();
}

Solution 5

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:

int hashcode() {
    int hash = 1;
    for (int val : this.values) {
        hash = hash * value;
    }
    return hash;
}

Consider what happens if an element of this.values is zero ...

Share:
22,742

Related videos on Youtube

OscarRyz
Author by

OscarRyz

Software Developer who happens to like writing code. Here are some interesting answers you might like to upvote :") Why java people frequently consume exception silently ? Coding in Other (Spoken) Languages How to create an string from the contents of a file History of Objective-C square brackets (as I remember it) ( visible only to >10k users )

Updated on July 09, 2022

Comments

  • OscarRyz
    OscarRyz almost 2 years

    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.

  • OscarRyz
    OscarRyz over 14 years
    Is the HashCodeBuilder source code online? ... .I'll look at it.
  • OscarRyz
    OscarRyz over 14 years
    it says: string.hashCode * 37 + intValue!! enough for me !! Thank you
  • OscarRyz
    OscarRyz over 14 years
    Doh!.. sometimes I miss this kinds of solutions !! Yeah I don't want to add another library. Thanks for the advice
  • Stephen C
    Stephen C over 14 years
    @aperkins: it is simpler to just write "return (myString + myInteger).hashCode()". The Java compiler will compile this to the equivalent sequence of StringBuilder.append calls.
  • Stephen C
    Stephen C over 14 years
    @perkins: another thing, if you are really concerned about speed, then this approach is significantly slower than calculating and combining component hashcodes.
  • Steve Kuo
    Steve Kuo over 14 years
    hashCode should be fast, it would be far better to take the string's hashCode and do a simple integer math operation with the integer.
  • aperkins
    aperkins over 14 years
    Speed concerns are probably true, however I have never noticed a significant slowdown using this method in the code we write. Usually our performance concerns are more related to wire-transfer or algorithm changes.