21

If I run the below code then the output is 2 which means that the set contains 2 elements. However I think that set should contain 1 since both the objects are equal based on hashcode() value as well as .equals() method. Seems like some obvious mistake in my understanding ?

package HELLO;

import java.util.HashSet;
import java.util.Set;

public class Test {

    public static void main(String[] args) throws Exception {
        Set<Alpha> s = new HashSet<Alpha>();
        Alpha a1 = new Alpha();
        Alpha a2 = new Alpha();
        s.add(a1);
        s.add(a2);
        System.out.println(s.size());
    }
}   

class Alpha {
    int a = 10;

    public int hashcode() {
        return a;
    }

    public boolean equals(Object obj) {
        return (obj instanceof Alpha && ((Alpha) obj).a == this.a);
    }

    public String toString() {
        return "Alpha : " + a;
    }
}

3 Answers 3

36

Your hashcode method does not override the Object class's hashCode method and thus your equals method breaks contract since it doesn't agree with the hashCode results, and you can have objects that are "equal" but have different hashCodes.

Remember: You should always use the @Override annotation when overriding methods as this will help you catch this and similar errors.

@Override  // ** don't forget this annotation
public int hashCode() { // *** note capitalization of the "C"
  return a;
}

Also, you will want to improve your code formatting, especially when posting code here for our review. We will be able to better understand your code and help you if it conforms to standards (that's why standards exist). So try to keep your indentations consistent with all code lines that are in the same block indented at the same level, and you will want to be sure that base level code, including imports, outer class declarations and its end curly brace, is flush left:

import java.util.HashSet;
import java.util.Set;

public class Test {

   public static void main(String[] args) throws Exception {
      Set<Alpha> s = new HashSet<Alpha>();
      Alpha a1 = new Alpha();
      Alpha a2 = new Alpha();
      s.add(a1);
      s.add(a2);
      System.out.println(s.size());
   }
}

class Alpha {
   int a = 10;

   @Override
   public int hashCode() {
      return a;
   }

   public String toString() {
      return "Alpha : " + a;
   }

   @Override
   public boolean equals(Object obj) {
      if (this == obj)
         return true;
      if (obj == null)
         return false;
      if (getClass() != obj.getClass())
         return false;
      Alpha other = (Alpha) obj;
      if (a != other.a)
         return false;
      return true;
   }
}

For a beautiful review on this, please read: Overriding equals and hashCode in Java

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks! Would never forget to use @Override anymore :)
@snow_leopard: it's a great habit to get in to. Good luck!
Besides "@Override" I also had to add a line in the equals function, otherwise the set was not able to detect duplicates and always contained an object with the same content multiple times: if(this.hashCode() == msg.hashCode()) return true;
@sven: I actually strongly recommend against your line of code since it is the exact opposite of what the equals and hashCode contract stipulates. Your need of that line suggests that there may be something else wrong with your equals method.
@hoverkraft: You are right, I had an error in equals() what returned false in a wrong case., so that multiple entries occured. Bad idea to check for hash in equals().
4

The @Overrides annotation is to override the method with the same name in the super class".

@Override
public int hashCode() {
    return a;
}

@Override
public boolean equals(Object obj) {
    return (obj instanceof Alpha && ((Alpha) obj).a == this.a);

}

@Override
public String toString() {
    return "Alpha : " + a;
}

Comments

4

your method hashcode should be named hashCode (capital letter "C").

If you plan on overriding methods you should use the @Override annotation.

If you had used that annotation, you'd have noticed the problem earlier as the code wouldn't have compiled.

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.