Reputation: 1253
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
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
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
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
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