3

I need to write an equals() method for the teams class that is consistent with the provided hashcode method

HashCode method

 public int hashCode()
   {
      return this.getPro().hashCode() 
             + this.getTeam().hashCode(); 
   }

My equals method, but wont work

public boolean equals(Object obj)
   {
     ClassName pro = (ClassName) obj;
     return (this.getPro().hashCode() == pro.getPro());
             (this.getTeam().hashCode() == pro.getTeam());
   }

Any help would be good

Colin Hebert
  • 91,525
  • 15
  • 160
  • 151
user445714
  • 383
  • 1
  • 9
  • 24
  • 1
    You are comparing hashCodes with objects. That isn't going to work. What are you trying to accomplish? What do you think hashCode() does? – Kirk Woll Sep 12 '10 at 18:43
  • If you are going to put objects into a HashSet or HashMap, then two objects that are equal must return the same hashCode, and two objects that return different hashCodes must not be equal. Two unequal objects can return the same hashCode (there are 4 billion possible hashCodes but many more possible Strings for instance). You can't define equals() in terms of hashCode(); it may say that two unequal objects are equal. – Mark Lutton Sep 12 '10 at 19:11

2 Answers2

3

Here you compare an hashcode (an int) to an object. Plus there is a semicolon in the middle of your statement.

You should try this instead :

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    MyClass myClass = (MyClass) o;

    if (!pro.equals(myClass.pro)) return false;
    if (!team.equals(myClass.team)) return false;

    return true;
}

Here you compare the content of objects.


After @Bart K. comment here is the way to write your equals() method if team or pro are nullable :

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    MyClass myClass = (MyClass) o;

    if (pro != null ? !pro.equals(myClass.pro) : myClass.pro != null) return false;
    if (team != null ? !team.equals(myClass.team) : myClass.team != null) return false;

    return true;
}

Resources :

On the same topic :

Community
  • 1
  • 1
Colin Hebert
  • 91,525
  • 15
  • 160
  • 151
  • `equals(...)` should also check for `obj == null`. – Bart Kiers Sep 12 '10 at 18:47
  • It depend if pro and team are nullable or not. And as they don't seem to be nullable (cf. OP `hashCode()`) it's not really necessary. – Colin Hebert Sep 12 '10 at 18:48
  • No, I didn't mean `pro` or `team` to be null but `obj`. For example, an `ArrayList` can contain `null` references and if you do a `contains(instanceOfClassName)` on it, your implementation would throw a NPE when comparing a `null` to `this`. – Bart Kiers Sep 12 '10 at 18:52
  • My bad, you're right, I edited the code with a better equals method. – Colin Hebert Sep 12 '10 at 18:53
  • Thumbs up for not putting `this` in front of method invocations. – Steve Kuo Sep 13 '10 at 01:39
2
  1. The hash of two objects being equal does not mean the two objects are equal.
  2. To check if two conditions are both satisfied, use &&.

Thus,

public boolean equals(Object obj)
   {
     ClassName pro = (ClassName) obj;
     return this.getPro() == pro.getPro() && this.getTeam() == pro.getTeam();
   }

Still, your hashCode() will not generate good hash, and equals() will fail in many cases (e.g. comparing with a non-ClassName or null). See Overriding equals and hashCode in Java for how to implement them correctly. Assuming no derived class, try

@Override public boolean equals(Object obj) {
   if (obj == this) return true;
   if (!(obj instanceof ClassName)) return false;
   ClassName pro = (ClassName)obj;
   <sometype> thisPro = getPro();
   if (thisPro == null || !thisPro.equals(pro.getPro()) return false;
   <sometype> thisTeam = getTeam();
   if (thisTeam == null || !thisTeam.equals(pro.getTeam()) return false;
   return true;
}
Community
  • 1
  • 1
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
  • 2
    I wouldn't use the `==` to compare the objects in the `equals()` method. Most of the time (if not always) if the content of the objects is equal, then the objects themselves are equal. – Colin Hebert Sep 12 '10 at 19:00
  • The condition (obj == null) is redundant: (null instanceof ClassName) == false – meriton Sep 12 '10 at 19:11
  • @Colin: Oops I assumed `==` compares values instead of references. Fixed. – kennytm Sep 12 '10 at 19:12
  • What "equals" means is totally determined by what you are trying to do. For instance, you might base equality entirely on an ID field with no regard for any of the other contents. Generally two objects are equal if they both model the same concept (like 6/8 equals 3/4 (except in music)) or the same real-world object. If you have two objects, and you put both into a HashSet, and you expect that the set will then contain only one of them and you don't care which, then the two objects are equal. – Mark Lutton Sep 12 '10 at 19:22