7

Possible Duplicate:
Overriding equals and hashCode in Java

I am supposed to implement hashcode and equals for Custom class Person. Person consists of

firstname

lastname

I am supposed to implement equals and hashcode such that two people with firstname and lastname should return true for equals and should be accepted by Hashmap. I have implemented Person class like this:

public class Person {


    String firstname;
    String lastname;
    public Person(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }

    @Override
    public int hashCode() {
        // TODO Auto-generated method stub
        return firstname.hashCode()+lastname.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        // TODO Auto-generated method stub
    Person u=(Person) obj;

        return u.firstname.equals(firstname) && u.lastname.equals(lastname);
    }

}

Is the implementation of Hashcode correct here? Even though I am getting the expected result,I want to know if this implementation is correct?

omerbp
  • 3,803
  • 3
  • 28
  • 44
Dude
  • 7,818
  • 22
  • 60
  • 99
  • 2
    if either firstname or lastname is null your code will not work – Peter Feb 01 '13 at 14:15
  • Also, equals method returns true only if firstname and lastname are equal and not null. – Prasad Dec 25 '18 at 11:34
  • In terms of hashCode, we will say if it's good or bad instead of correct or wrong. Good hashCode() means there is less chance of conflict in a hashmap. – Leon Dec 19 '19 at 02:56

4 Answers4

8

There is a slight problem with your equals method because it will throw an exception if obj is null or not a Person, so you should add the following to the top of your equals:

if(obj==null || !(obj instanceof Person))
   return false;
Daniel Bo
  • 2,478
  • 1
  • 16
  • 28
MTilsted
  • 4,974
  • 9
  • 33
  • 64
  • It is only person object only that can call this method right? – Dude Feb 01 '13 at 14:20
  • 1
    The argument to the method might not be a person. Imagine what happens if someone does new Person().equals("My string"); – MTilsted Feb 01 '13 at 14:21
  • gotcha, many thanks!!, I should have thought of that. – Dude Feb 01 '13 at 14:23
  • 2
    (null instanceof Person) is always false, and (obj instanceof Person)==false is the same as !(obj instanceof Person). Therefore your code can be simplified to: if (!(obj instanceof Person)) return false; – Tobias May 02 '14 at 18:08
  • @Tobias or simply `return (obj instanceof Person && this.hashCode() == obj.hashCode());` – RecursiveExceptionException Aug 10 '16 at 02:02
  • @itzJanuary ugh, no! That'd be a bad bug because two Persons with the given names "FB" and "Ea" would then be regarded as equal (those two strings have the same hashCode). In general, different hashCode implies not equal values. But equal hashCode does not imply equal values. – Tobias Aug 10 '16 at 09:47
  • @Tobias True. Don't sleep and think kids! – RecursiveExceptionException Aug 10 '16 at 11:32
4

There is an excellent discussion of proper equals and hashCode implementation here:

Whenever a.equals(b), then a.hashCode() must be same as b.hashCode()

This is the only rule that matters. There is no correct implementation of a hashCode besides this one rule. There are better and worse hash codes in terms of performance and hash collisions, but that's another topic altogether.

Your code appears to be correct according to that rule, because if a.equals(b), then firstname.hashCode()+lastname.hashCode() should be the same value for both a and b.

Community
  • 1
  • 1
mellamokb
  • 53,762
  • 11
  • 101
  • 131
1

Your code is fine. String has an good hash algorithm and just adding hashes is the most efficient way for hashing multiple Strings in Java.

th3falc0n
  • 1,375
  • 11
  • 32
  • 1
    the fact that two `String`s have good hash functions do not guarantee that sum of two hash values are as well distributed (thinking bitwise) – posdef Feb 01 '13 at 14:21
  • Well actually 2 Strings with 2 characters should in this way have an as good distribution as 1 string with 4 characters. Except for the case that the both Strings equal. – th3falc0n Feb 01 '13 at 14:26
0

hashCode() is correct in the sense that it will work (assuming that the strings firstname and lastname are not null) - i.e. the method will return an int. Whether it's a good solution or not is a much longer story, which I am sure you can check up on using the search field above ;)

Here's an interesting question I've asked a while back regarding custom implementations of hashCode(): Using a larger prime as a multiplier when overriding hashCode()

Community
  • 1
  • 1
posdef
  • 6,196
  • 10
  • 40
  • 85