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?

3
  • 2
    if either firstname or lastname is null your code will not work Commented Feb 1, 2013 at 14:15
  • Also, equals method returns true only if firstname and lastname are equal and not null. Commented Dec 25, 2018 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. Commented Dec 19, 2019 at 2:56

4 Answers 4

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;
Sign up to request clarification or add additional context in comments.

7 Comments

It is only person object only that can call this method right?
The argument to the method might not be a person. Imagine what happens if someone does new Person().equals("My string");
gotcha, many thanks!!, I should have thought of that.
(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 or simply return (obj instanceof Person && this.hashCode() == obj.hashCode());
|
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.

Comments

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.

2 Comments

the fact that two Strings have good hash functions do not guarantee that sum of two hash values are as well distributed (thinking bitwise)
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.
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()

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.