Win a copy of Mesos in Action this week in the Cloud/Virtualizaton forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Justify output of the HashSet code

 
Nilesh Chawda
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please help me to understand the output of following program.

[Added code tags - see UseCodeTags for details]

Output I found is : 3 false false true false true

If comment the line defined by #1 then output will changes to : 3 true false true true true

Please help me to understand the effect of line #1, it is making in the code (1) when it is not commented and (2) when it is commented.
 
Joanne Neal
Rancher
Posts: 3742
16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First you ned to edit your post to UseCodeTags. This will make your code a lot more readable and make it more likely that people will read your post.

Then you need to tell us which part you don't understand. It's a waste of other people's time explaining things you already know.
 
Jesper de Jong
Java Cowboy
Saloon Keeper
Posts: 15279
39
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In line 12, you are comparing String objects with == instead of with equals().

Note that == will only return true when you use it on objects (rather than primitive values) when the two operands on both sides of the == refer to the exact same object. It will return false if the operands refer to different objects, even if those objects seem to contain the same value.

What makes it a little bit more complicated is that Java reuses literal strings. So if you use for example the string literal "a" multiple times in a program, then Java is smart enough to make just one String object that contains "a", and it uses that object every time you use "a" in your source code. That's why something like this will print true:

Note that if you explicitly create a new String object, the result would be false:

To make your code do what you expect, use equals() in line 12 to compare ((Dog)o).s and this.s instead of ==.

Another thing that is a bit strange is that you're using the name list for your variable that is actually a Set. A Set is not a list. You should think of a Set as a bag that contains elements in no particular order, which is different from a list (which does have a defined order).
 
Campbell Ritchie
Sheriff
Pie
Posts: 48940
60
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

You can cause no end of confusion with variable names. Calling a Set “list” is one way to do that.

You may find your explanation here.
 
Nilesh Chawda
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you ! For providing solution but I have 1 more doubt.

Please refer this new program :



please help me to understand why the output for :
#2 is false
#3 is false
#5 is false


 
Matthew Brown
Bartender
Posts: 4567
8
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can run into problems making equals() and hashCode() dependent on mutable fields, and this is one example why.

Although in #2 you're looking for the actual object that's in the Set (so an equals() comparison will succeed), it doesn't have the same hash code as it had when you added it to the Set. So it's not in the bucket that it "should" be in, and the HashSet algorithm won't find it. If the hash code changes after it's been added the HashSet has no way of knowing this.

#3 the same reason - the hash code does not match the value it was added with.

#5 is false because although it has the right hash code, it will fail an equals() comparison, because the original d no longer contains "aaa".
 
Campbell Ritchie
Sheriff
Pie
Posts: 48940
60
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That looks like the same question, but with the list corrected.
Did the Odersky Spoon and Venners link not help?
 
Mansukhdeep Thind
Ranch Hand
Posts: 1158
Eclipse IDE Firefox Browser Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just another example of how necessary it is to appropriately override hashCode() and equals() methods of the Object class, especially for hashed collections. It is dangerous to base the implementation of hashCode() on mutable fields of the object.
 
Nilesh Chawda
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Thanks ! I got it, how that output is coming.

It is mutable object that is making difference.

Now I have also referred the Article of Odersky Spoon. It is just an awesome explanation.
 
Mansukhdeep Thind
Ranch Hand
Posts: 1158
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Follow master Ritchie and thou shall find more awesome things about Java.
 
Campbell Ritchie
Sheriff
Pie
Posts: 48940
60
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, because you changed the state of the mutable object, its hash code changed, so you are looking in the wrong bucket. You can repeat the procedure with new Dog("a") and again find you are looking in the wrong bucket. You can tell which bucket the references go into because you know they go into buckets[Math.abs(h % c)] where h is the hash code and c is the capacity, which defaults to 16. The implementation probably users something different from abs and %, as discussed in this thread.

I thought that was a well‑known problem, but I couldn’t find it in the Java Tutorials nor the Specification nor the API for HashSet. It is in Odersky Spoon and Venners, however.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic