Sammy
Sammy

Reputation: 953

Class not using overridden equals

Why does it not reach the print line "here"? In other words, why is it not using my overridden equals? Thanks in advance

import java.util.*;
class NumberClass extends Object{
    private int number;

    public NumberClass(int n){
        number=n;

    }
    @Override
    public boolean equals(Object other){
        System.out.println("here");
        return false;
    }
    @Override
    public String toString(){

        return number+"";
    }   
}
public class HelloWorld {
    public static void main(String[] args) {

        Set <NumberClass> set= new HashSet<NumberClass>();
        set.add(new NumberClass(0));
        set.add(new NumberClass(0));
        System.out.println(set);
    }

}

Upvotes: 1

Views: 151

Answers (2)

Jayamohan
Jayamohan

Reputation: 12924

While comparing the objects,

  • equals method will not be called if hashCode differs
  • hashCode method will not be called if (obj1 == obj2)

So in your case since you haven't overridden the hashCode method the hash code is different so equals is not being called. Try Overriding hashCode method as below, your equals method will be called.

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

Object.equals API in Java states as below

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

So remember to override hashCode when you are overriding equals method.

Upvotes: 1

Ted Hopp
Ted Hopp

Reputation: 234795

This is because HashSet uses the hash code to test whether an object is already in the set and only uses equals if there is a collision. The default hash code for objects is an internal id, so just because the two objects are equal doesn't mean they have the same hash code. In this case, there clearly wasn't a collision, so there was no need for the HashSet to call equals.

This is why you should always override hashCode when you override equals. See this article for more info on this topic. You should write a hashCode method that returns equal hash values for objects that are equals. For instance:

public int hashCode() {
    return number;
}

The general requirement for hashCode is that objects that satisfy equals() should return the same hash code. Note that there's no requirement that objects that fail an equals() test have different hash codes. If you return a constant (like Jayamohan suggests), that satisfies the hashCode contract; however, this will completely eliminate the benefits of using a HashSet and you might as well go with a simple ArrayList.

Upvotes: 4

Related Questions