JPG
JPG

Reputation: 1253

What is the difference between Object's equals method in String Class and Object's equal method in custom class

I am not able to understand the behaviour (distinction) of equals method in String class and then overriding that equals method manually in custom class.

According to java, if we want two objects to be equal, then we should override equals method to check the equality among them. So, I made a Dog class and override equals method in that class. Further to check the equality among objects I used Set type collection as it does not allow duplicate. But I was confused to see the output. Here is my code:

import java.util.*;

class Dog{
    int type;

    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }

    public boolean equals(Object o){
    if((o instanceof Dog) && ((Dog)o).getType()==this.getType()){
        return true;
    }
    else{
        return false;
    }
}
}
public class CheckEquality {
    public static void main(String[] args) {
        Dog d1=new Dog();
        Dog d2=new Dog();

        d1.setType(12);
        d2.setType(12);
        Set set=new HashSet();
        if(set.add(d1)){
            System.out.println("d1 added");
        }
        if(set.add(d2)){
            System.out.println("d2 added");
        }

        String s1=new String("ad");
        String s2=new String("ad");
        //String s1="ad";
        //String s2="ad";
        Set set2=new HashSet();
        if(set2.add(s1)){
            System.out.println("s1 added");
        }
        if(set2.add(s2)){
            System.out.println("s2 added");
        }

    }
}

output:

d1 added
d2 added
s1 added

what I expected:

d1 added
s1 added

can any one tell me why am I getting d2 addedd statement, when it can be seen that object with same type has already been added to Set.

While in contrary, String does NOT allow the statement s2 added. Why is it so?. Can anyone clear my doubts.

Upvotes: 1

Views: 1080

Answers (4)

Sachin Pete
Sachin Pete

Reputation: 21

If you does't override hashcode method there is collision issue while storing object in hashset. Hashset internally uses hashtable to key and value pair.

Since you must have to override the hashcode so that hashset found that same hashcode then it will internally call the equals the method.

@Override
public int hashCode() {
    return type.hashcode();
}

Upvotes: 0

wassgren
wassgren

Reputation: 19221

The Set-implementation HashSet is expected to find values by using the hashCode. Your object does not provide a good hashCode but instead uses the version from Object. When implementing equals you should generally also always implement hashCode. It is simply a best practice.

In Java 8 you can provide a good and efficient hash by using the following code:

Objects.hash(value1, value2, value3);

If used properly the HashSet will work as expected. For the simple Dog-class the type can be returned but for more complex objects that contains more attributes the Objects.hash or similar is recommended.

Upvotes: 2

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85779

Because you have to override hashCode as well. Check the contract of Object#equals:

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.

Add this to your Dog class:

public class Dog {
    @Override
    public int hashCode() {
        return this.type;
    }
}

This is just a basic example. It would be better if type is a final field. From Object#hashCode:

Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.

Upvotes: 3

sol4me
sol4me

Reputation: 15708

You are missing hashCode method.

This hash is used by other code when storing or manipulating the instance – the values are intended to be evenly distributed for varied inputs in order to use in clustering. This property is important to the performance of hash tables and other data structures that store objects in groups ("buckets") based on their computed hash values

You can use Objects class to generate hashcode.

public class Dog {
    @Override
    public int hashCode() {
        return Objects.hash(type);
    }
}

Upvotes: 3

Related Questions