File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Beginning Java and the fly likes Justify output of the HashSet code Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Justify output of the HashSet code" Watch "Justify output of the HashSet code" New topic
Author

Justify output of the HashSet code

Nilesh Chawda
Greenhorn

Joined: Mar 07, 2013
Posts: 8
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

Joined: Aug 05, 2005
Posts: 3446
    
  12
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.

Joanne
Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14107
    
  16

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).


Java Beginners FAQ - JavaRanch SCJP FAQ - The Java Tutorial - Java SE 7 API documentation
Scala Notes - My blog about Scala
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38357
    
  23
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

Joined: Mar 07, 2013
Posts: 8
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

Joined: Apr 06, 2010
Posts: 4363
    
    8

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

Joined: Oct 13, 2005
Posts: 38357
    
  23
That looks like the same question, but with the list corrected.
Did the Odersky Spoon and Venners link not help?
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

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.


~ Mansukh
Nilesh Chawda
Greenhorn

Joined: Mar 07, 2013
Posts: 8

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

Joined: Jul 27, 2010
Posts: 1157

Follow master Ritchie and thou shall find more awesome things about Java.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38357
    
  23
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.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Justify output of the HashSet code