This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Beginning Java and the fly likes Searching in a Map Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Searching in a Map" Watch "Searching in a Map" New topic
Author

Searching in a Map

ven jovovich
Ranch Hand

Joined: Sep 06, 2012
Posts: 33
Hi everyone,
In the following code I think the second and last print statements should NOT print null, but unfortunately they do . Where am I going wrong?


Thanks.
Nikhil Sagar
Ranch Hand

Joined: Apr 21, 2012
Posts: 216

Welcome ven jovovich into the great world of java lovers,
You are getting null just because In this line.


when you are puting this key value in the HashMap it will go into the....say a Bucket with number 4, i said bucket number 4 because in your hashcode generating algorithm you will get 4 as a hashcode for this (d2) object.
Ok, But after that you changed the name inside the d2 Object, But it doesn't means that the bucket will automatically updates that means the bucket is still no 4.

Now when you try you search for this with key ,



it will generate again a hashcode for this particular Object and Unfortunetly it will be 3, So, Where to search for the corresponding value.
Yes, Of-course it will search for the corresponding value in the bucket no 3.
Thats why it will return you null because there is nothing in the bucket no 3 corresponding to this key.


OCPJP 6 86%
Javin Paul
Ranch Hand

Joined: Oct 15, 2010
Posts: 281

This is one of the reason that HashMap keys should be immutable, because you can not change immutable object once created so calling to hashCode() will always return same hashcode.


http://javarevisited.blogspot.com - java classpath - Java67 - java hashmap - java logging tips java interview questions Java Enum Tutorial
Nikhil Sagar
Ranch Hand

Joined: Apr 21, 2012
Posts: 216

Javin Paul wrote:This is one of the reason that HashMap keys should be immutable, because you can not change immutable object once created so calling to hashCode() will always return same hashcode.


Agree, But it is not always possible So,
I think If you make name field of Dog class private you can fix the problem for sure.
And there will be no fun if you always follow the conventions.

Javin Paul
Ranch Hand

Joined: Oct 15, 2010
Posts: 281

Hi Nikhil, I can bet you production issues will not be fun , better to be safe than sorry.
Nikhil Sagar
Ranch Hand

Joined: Apr 21, 2012
Posts: 216

Javin Paul wrote:Hi Nikhil, I can bet you production issues will not be fun , better to be safe than sorry.


You are Absolutely correct Jevin but , Sometimes during production by applying new things you can get better results than convention says.
And Friend, I and almost all java folks around world always use their own defined class' Objects as a key. I know it is good in the learning phase but you will not get much more by using that.
For example What if you want a Dog as a key and owner of that Dog as value.
Javin Paul
Ranch Hand

Joined: Oct 15, 2010
Posts: 281

Nikhil Sagar wrote:
Javin Paul wrote:Hi Nikhil, I can bet you production issues will not be fun , better to be safe than sorry.


You are Absolutely correct Jevin but , Sometimes during production by applying new things you can get better results than convention says.
And Friend, I and almost all java folks around world always use their own defined class' Objects as a key. I know it is good in the learning phase but you will not get much more by using that.
For example What if you want a Dog as a key and owner of that Dog as value.



Hi Nikhil,
I agree with you on learning part, learning by experience is good thing but you also need Guidance to learn right things and avoid misconception.
By the way If you want to use Dog as key than you should make it Immutable to avoid such issues. Value classes are actually good candidate to be Immutable.
Nikhil Sagar
Ranch Hand

Joined: Apr 21, 2012
Posts: 216

But i don't think that there is any need of make a whole class nearly perfectly immutable, just by making the key field private you used in equals() and (or) hashcode() you can achieve all desired results.
Am i Wrong Jevin ??
ven jovovich
Ranch Hand

Joined: Sep 06, 2012
Posts: 33
Thanks. Solved.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19649
    
  18

Although it isn't the cause of the error this time, you shouldn't use == for comparing Strings. You should always use the equals method.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Javin Paul
Ranch Hand

Joined: Oct 15, 2010
Posts: 281

Nikhil Sagar wrote:But i don't think that there is any need of make a whole class nearly perfectly immutable, just by making the key field private you used in equals() and (or) hashcode() you can achieve all desired results.
Am i Wrong Jevin ??


Yes you are fine, Until your code guarantee that hashCode will always return same value. by not making field final and just making it private can still cause issue if any method unintentionally modify it. By making it final , compiler will ensure it for you.
ven jovovich
Ranch Hand

Joined: Sep 06, 2012
Posts: 33
Rob Spoor wrote:Although it isn't the cause of the error this time, you shouldn't use == for comparing Strings. You should always use the equals method.


Could you please explain why you think it's better to do that? In String, equals() is defined as:



I dont see the advantage of using "equals()" to compare Strings.

Thanks.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19649
    
  18

That's only the start, as a shortcut to prevent having to check the entire String if you're checking the same object. If you check the entire method you'll see that if that if-statement is not executed, the String contents are checked.
ven jovovich
Ranch Hand

Joined: Sep 06, 2012
Posts: 33
Thanks a lot Rob. Still wondering how I missed the second if block...


...but then again, if two String objects are "==" they are "equal" (equals() returns true) and if they are not "==", equals() should return false since same strings (lowercase s) are always "=="... the String pool comes into play and all...
So is that second if block really necessary?

Thanks.
Nikhil Sagar
Ranch Hand

Joined: Apr 21, 2012
Posts: 216

ven jovovich wrote:Thanks a lot Rob. Still wondering how I missed the second if block...


...but then again, if two String objects are "==" they are "equal" (equals() returns true) and if they are not "==", equals() should return false since same strings (lowercase s) are always "=="... the String pool comes into play and all...
So is that second if block really necessary?

Thanks.


Yes Ven that is absolutely necessary because there are two types by which you can make a String Object.
you already know first but what if you make two String Objects by new keyword and same arguments.
For example,

In that case '==' will never return true that means first if condition fails.
But they are meaningfully equal.
So, now the Second if condition comes into play.
Just to make it more understandable to you i am posting a code, try to predict its output and reasons behind it.
Nikhil Sagar
Ranch Hand

Joined: Apr 21, 2012
Posts: 216

Javin Paul wrote:
Nikhil Sagar wrote:But i don't think that there is any need of make a whole class nearly perfectly immutable, just by making the key field private you used in equals() and (or) hashcode() you can achieve all desired results.
Am i Wrong Jevin ??


Yes you are fine, Until your code guarantee that hashCode will always return same value. by not making field final and just making it private can still cause issue if any method unintentionally modify it. By making it final , compiler will ensure it for you.


But what if i need to change the value inside that field just because Now my existing Dog (name was Tiger) have a new name (new name is Viper).
i mean without affecting the hashcode means, hashcode for the new value is still same as the old one but i just want to update the new name.
How can i do that ??
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7494
    
  18

Nikhil Sagar wrote:But what if i need to change the value inside that field just because Now my existing Dog (name was Tiger) have a new name (new name is Viper).
i mean without affecting the hashcode means, hashcode for the new value is still same as the old one but i just want to update the new name. How can i do that ??

Simply put: if name is part of the identification of a Dog (ie. Dog.equals(Dog) contains any comparison of names), you CAN'T.

equals() and hashCode() must always be in sync, so if you change any field in Dog that is referenced in equals(), you must also change the hashCode() calculation.

Winston


Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19649
    
  18

Well, it's of course possible to let hashCode use less fields than equals. Let's say you have a class with an ID and a name field. equals checks both ID and name. If you let hashCode use only ID that's just fine.

You can even choose to use no fields at all, but that means hashCode should return a constant which means that a HashMap essentially turns into a LinkedList, as there will be only one bucket.
ven jovovich
Ranch Hand

Joined: Sep 06, 2012
Posts: 33
Thanks a lot Nikhil.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7494
    
  18

Rob Spoor wrote:Well, it's of course possible to let hashCode use less fields than equals. Let's say you have a class with an ID and a name field. equals checks both ID and name. If you let hashCode use only ID that's just fine.

Seems an odd way to go about things if ID is already a unique identifier. Surely better to have a separate Comparator which compares by name, no?

@Nikhil: The fact is that you only need hashCode() if you plan on putting your object into a hashed collection; however, since they are extremely useful, the normal rule of thumb is to always implement equals() and hashCode() together, and to always keep them in sync (ie, have them work with the same fields).

Winston
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Searching in a Map
 
Similar Threads
Problem faced in using hashset(comparison of equal elements)
Map Doubt
question about null object
HashMap
Please help