Reputation: 241
I have this program:
import java.util.*;
public class test {
private String s;
public test(String s) { this.s = s; }
public static void main(String[] args) {
HashSet<Object> hs = new HashSet<Object>();
test ws1 = new test("foo");
test ws2 = new test("foo");
String s1 = new String("foo");
String s2 = new String("foo");
hs.add(ws1);
hs.add(ws2);
hs.add(s1);
hs.add(s2); // removing this line also gives same output.
System.out.println(hs.size());
}
}
Note that this is not a homework. We were asked this question on our quiz earlier today. I know the answers but trying to understand why it is so.
The above program gives 3 as output.
Can anyone please explain why that is?
I think (not sure):
The java.lang.String
class overrides the hashCode
method from java.lang.Object
. So the String
objects with value "foo" will be treated as duplicates. The test class does not override the hashCode
method and ends up using the java.lang.Object
version and this version always returns a different hashcode for every object, so the two test objects being added are treated as different.
Upvotes: 3
Views: 340
Reputation: 11
Hashcode is used to narrow down the search result. When we try to insert any key in HashMap
first it checks whether any other object present with same hashcode and if yes then it checks for the equals()
method. If two objects are same then HashMap
will not add that key instead it will replace the old value by new one.
Upvotes: 1
Reputation: 8278
Below are few (well quite many) bullets refarding the equals and hashcode from my preparations to SCJP. Hope it helps:
In addition if you implement equals and hashcode the transient fields (if any) must be treated properly.
The Commons have nice implementation for EqualsBuilder and HashcodeBuilder. They are available in Coomons Lang http://commons.apache.org/lang/
I use them whenevr I need to implement the equals and the hashcode.
Upvotes: 0
Reputation: 2941
In this case it's not about hashCode()
but is about equals()
method. HashSet is still Set, which has semantic of not allowing duplicates. Duplicates are checked for using equals()
method which in case of String will return true
However for your test
class equals()
method is not defined and it will use the default implementation from Object
which will return true only when both references are to the same instance.
Method hashCode()
is used not to check if objects should be treated as same but as a way to distribute them in collections based on hash functions. It's absolutely possible that for two objects this method will return same value while equals()
will return false.
P.S. hashCode
implementation of Object
doesn't guarantee uniqueness of values. It's easy to check using simple loop.
Upvotes: 5
Reputation: 2711
In fact, it is not about overriding the hashcode()
, it is about equals
method. Set does not allow duplicates. A duplicate is the one where the objects are logically equal.
For verifying you can try with
System.out.println(ws1.equals(ws2));
System.out.println(s1.equals(s2));
If the objects are equal, only one will be accepted by a set.
Upvotes: 0