1

I have the following java class:

public class Person{
   String name;  //a unique name
   Long DoB;     //a unique time
   .
   .
   .
   @Override
   public int hashCode(){
     return name.hashCode() + DoB.hashCode();
   }

}

Is my hashCode method correct (i.e. would it return a unique number of all combinations.

I have a feeling I'm missing something here.

6
  • The equals override. You might want to multiply the long by something odd, e.g., 31. Commented Nov 26, 2014 at 15:13
  • no, it won't be. hash(a) + hash(b) != hash(a+b). while not exactly easy to do, someone could probably find a completely different SINGLE string that hashes to the same value as your combined hash(a)+hash(b). Commented Nov 26, 2014 at 15:13
  • @DaveNewton I have the equal override too. should I add it to the question? Commented Nov 26, 2014 at 15:14
  • @nafas No, it's more of a "make sure you do this right" comment. I might add that you have it, though, to avoid the inevitable pile-on. Commented Nov 26, 2014 at 15:16
  • 1
    It can not be unique (there are more Longs in DoS alone than there are possible hashes), and it does not have to be. The question should be: is it unique enough? Commented Nov 26, 2014 at 15:16

6 Answers 6

3

You could let java.util.Arrays do it for you:

return Arrays.hashCode(new Object[]{ name, DoB });
Sign up to request clarification or add additional context in comments.

Comments

1

You might also want to use something more fluent and more NPE-bulletproof like Google Guava:

@Override
public int hashCode(){
    return Objects.hashCode(name, DoB);
}

@Override
public boolean equals(Object o) {
    if ( this == o ) {
        return true;
    }
    if ( o == null || o.getClass() != Person.class ) {
        return false;
    }
    final Person that = (Person) o;
    return Objects.equal(name, that.name) && Objects.equal(DoB, that.DoB);
}

Edit:

IntelliJ IDEA and Eclipse can generate more efficient hashCode() and equals().

1 Comment

+1 I didn't show my equals method, its almost same as yours Except that I don't checking if o is null.
1

Aside for the obvious, which is, you might want to implement the equals method as well...

  • Summing two hash codes has the very small risk of overflowing int
  • The sum itself seems like a bit of a weak methodology to provide unique hash codes. I would instead try some bitwise manipulation and use a seed.

Comments

0

See Bloch's Effective Java #9.

But you should start with an initial value (so that subsequent zero values are significant), and combine the fields that apply to the result along with a multiplier so that order is significant (so that similar classes will have much different hashes.)

Also, you will have to treat things like long fields and Strings a little different. e.g., for longs:

(int) (field ^ (field>>>32))

So, this means something like:

@Override public int hashCode() {
   int result = 17;
   result += name.hashCode() == null ? 0 : name.hashCode();
   result = 31 * result + (int) (DoB ^ (DoB >>> 32));
   return result;
}

31 is slightly magic, but odd primes can make it easier for the compiler to optimize the math to shift-subtraction. (Or you can do the shift-subtraction yourself, but why not let the compiler do it.)

Comments

0

usually a hashcode is build like so:

   @Override
   public int hashCode(){
     return name.hashCode() ^ DoB.hashCode();
   }

but the important thing to remember when doing a hashcode method is the use of it. the use of hashcode method is to put different object in different buckets in a hashtable or other collection using hashcode. as such, it's impotent to have a method that gives different answers to different objects at a low run time but doesn't have to be different for every item, though it's better that way.

This hash is used by other code when storing or manipulating the instance – the values are intended to be evenly distributed for varied inputs in order to use in clustering. This property is important to the performance of hash tables and other data structures that store objects in groups ("buckets") based on their computed hash values

and

The general contract for overridden implementations of this method is that they behave in a way consistent with the same object's equals() method: that a given object must consistently report the same hash value (unless it is changed so that the new version is no longer considered "equal" to the old), and that two objects which equals() says are equal must report the same hash value.

Comments

0

Your hash code implementation is fine and correct. It could be better if you follow any of the suggestions other people have made, but it satisfies the contract for hashCode, and collisions aren't particularly likely, though they could be made less likely.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.