• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

What difference exactly will come for this case if I override hashcode and equals?

 
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have the below class


and



I could add 2 employee objects to the hashmap and when I checked the size it was 2. What difference exactly will it make if my Employee class overrides hashcode and equals methods?
thanks

 
Rancher
Posts: 4801
50
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What do you think will happen?
Can you explain how overriding those methods will change how those two objects are treated?

You might also want to show what the new methods look like.
 
Marshal
Posts: 79178
377
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
. . . and what about the following code?You should have learnt that within six months of starting programming Java®.
Why have you written a class with non‑private fields and a no‑arguments constructor?
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:. You should have learnt that within six months of starting programming Java®.



You are right.Unfortunately that did not happen. What may be the reason that a developer could not learn that within say first 6 months despite his/her intention to learn ?

Thanks.Your comments have made me realise that I need to think and analyze with a better approach.
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:. .



Thanks.Yes, that's the reason why overriding hashcode and equals is required.Let me now attempt to override these in the right manner and see the change in results.
 
Campbell Ritchie
Marshal
Posts: 79178
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Monica Shiralkar wrote:. . . . What may be the reason that a developer could not learn that within say first 6 months despite his/her intention to learn ? . . .

Don't know. Were you taught well? Did you take a course or try to teach yourself from books?

I hope you meant, “did not learn,” rather than, “could not learn,”.
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

Monica Shiralkar wrote:. . . . What may be the reason that a developer could not learn that within say first 6 months despite his/her intention to learn ? . . .

Don't know. Were you taught well? Did you take a course or try to teach yourself from books?

I hope you meant, “did not learn,” rather than, “could not learn,”.



I had understood it at that time when I had learnt more than a decade back but had forgotten now. Let me run the example and understand it more clearly.
 
Campbell Ritchie
Marshal
Posts: 79178
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Predict what will happen with and without overridden methods and then verify your prediction by running some code.
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Predict what will happen with and without overridden methods and then verify your prediction by running some code.



prediction: Without overriding hashcode and equals, on trying to use get command to get value using such a key, it will not be able to fetch. Problem will come surely.  But what problem exactly will come, that I am not sure. I will try and determine this.
                After overriding hashcode and equals, on trying to use get command to get value using such a key, one would be able to fetch successfully without any issue. But I am not sure what implementation to give in the methods overriding them. I will try and determine this.

 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
My prediction was: Without overriding hashcode and equals, on trying to use get command to get value using such a key, it will not be able to fetch.

This prediction went wrong to my surprise and created confusion now.


The below code:



returned

retrieving emp1->1



If I can retrieve successfully without overriding equals and hashcode then what benefit will I get by overriding ?




 
Bartender
Posts: 2911
150
Google Web Toolkit Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Monica Shiralkar wrote:My prediction was: Without overriding hashcode and equals, on trying to use get command to get value using such a key, it will not be able to fetch.


This assumption is incorrect. I think that your assumption would be easily clarified with 2 changes.

Change 1: Check if the hashcode is same or not in your program:

Change 2: Checking with same hashcode for both objects:


If the output confuses you further, then I would suggest reading more on how the Map works.
 
Dave Tolls
Rancher
Posts: 4801
50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Monica Shiralkar wrote:
If I can retrieve successfully without overriding equals and hashcode then what benefit will I get by overriding ?



You could also try by changing the last couple of lines of your code above:


Between that and salvin's suggestion you should be able to work out the problem with not having a meaningful equals and hashcode when dealing with things like HashMaps.
 
Campbell Ritchie
Marshal
Posts: 79178
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Dave Tolls wrote:. . . you should be able to work out the problem . . . .

Don't expect us to explain the whole story.
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

salvin francis wrote:

If the output confuses you further, then I would suggest reading more on how the Map works.



No the output did not confuse me and was as expected.




Expectation : Different hashcode.
Result : Different hashcode.



Expectation: Same hashcode
Result : Same hashcode


Is the above confusing ?  NO
If the above is not confusing then what is my confusion?

My confusion:  When without overriding , I am able do retrieve elements form the hashmap then why should I override hashcode?  This means that when without overriding hashcode by default it is creating unique hashcode for me which is allowing me to retrieve from the hashmap, then what is the need for me to override hashcode?


 
salvin francis
Bartender
Posts: 2911
150
Google Web Toolkit Eclipse IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Monica Shiralkar wrote:... what is the need for me to override hashcode?


Let's discuss the basics first. Please answer the below question to the best of your knowledge:

What is a hashcode ?
 
Dave Tolls
Rancher
Posts: 4801
50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Let's break your code down a bit.


Given the above class, what do I pass into getEmployeeInteger in order to retrieve the associated value in the map for "mary"?
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

salvin francis wrote:

Monica Shiralkar wrote:... what is the need for me to override hashcode?


Let's discuss the basics first. Please answer the below question to the best of your knowledge:

What is a hashcode ?



A unique number associated with every object (since hashcode method is of object class). Hashing is used by certain collections like Hashset, Hashmap for good retrieval performance.
 
Campbell Ritchie
Marshal
Posts: 79178
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Monica Shiralkar wrote:

salvin francis wrote:. . . What is a hashcode ?

A unique number associated with every object (since hashcode method is of object class).

No.

Hashing is used by certain collections like Hashset, Hashmap for good retrieval performance.

That is only a part of the whole story, probably only a small part.
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Dave Tolls wrote:Let's break your code down a bit.


Given the above class, what do I pass into getEmployeeInteger in order to retrieve the associated value in the map for "mary"?




Thanks.


     For the line 11, I am assuming you meant and not again.


"in order to retrieve the associated value in the map for "mary"



I retrieved the associated in map for "mary", i.e 3 simply by doing the below:




full code:



This is the default case, where I have not overridden hashcode at all. Calling hashcode on the three objects returns different integers.
Just for testing if I override hashcode and return the same hashcode value say 100, then also the same result.

In both the cases, I am able to retrieve it (i.e get output as 3)  using
 
Marshal
Posts: 8857
637
Mac OS X VI Editor BSD Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@OP

Once you figure all out what has been discussed before. It is also important to understand in general why hashCode() and equals() methods are necessary using hash based data structures.

Do both hashCode() and equals() methods are always being used when calling myMap.get(...)? Explain your answer.
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Liutauras Vilda wrote:

Do both hashCode() and equals() methods are always being used when calling myMap.get(...)? Explain your answer.



Yes, that has been my understanding that we can do this only if the class of which these objects are , overrides hashCode method. But what I can see by running the code the last post of mine, is that it is happening fine in all the 3 cases below:
Case : Employee class does not override hashcode and equals.  Result : Using getEmployeeInteger(emp3) one can successfully retrieve the value as 3.
Case : Employee class overrides hashCode and returns a hardcoded value 100 everytime.  Result : Using getEmployeeInteger(emp3) one can successfully retrieve the value as 3.
 
Liutauras Vilda
Marshal
Posts: 8857
637
Mac OS X VI Editor BSD Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Monica Shiralkar wrote:In both the cases, I am able to retrieve it (i.e get output as 3)  using
System.out.println("Result of get->"+ getEmployeeInteger(emp3));
...
But what I can see by running the code the last post of mine, is that it is happening fine in all the 3 cases below


Make your changes to look as such:

And what you get then (in all your cases)? What would you expect to get?

 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks

Case : Employee class does not override hashcode and equals.  
Output:
Result of get for e3Clone->null


Case : Employee class overrides hashCode and returns a hardcoded value 100 everytime.  
Output:

Result of get for e3Clone->null

Expected result was also the same (since this object was never inserted in the map).

Full code:

 
Liutauras Vilda
Marshal
Posts: 8857
637
Mac OS X VI Editor BSD Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Monica Shiralkar wrote:...that has been my understanding that we can do this only if the class of which these objects are , overrides hashCode method. But what I can see by running the code the last post of mine, is that it is happening fine in all the 3 cases below...

...Expected result was also the same (since this object was never inserted in the map).


I've created almost finished crazy lottery app. So with your tools, how you'd finish the app?

At line 8 Joe should figure out how much he won. Please fill in Line 20 so it returns a correct result. Note: program is complete, except Line 20.
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the simple exercise.

Liutauras Vilda wrote:

At line 8 Joe should figure out how much he won. Please fill in Line 20 so it returns a correct result. Note: program is complete, except Line 20.



I tried filling . However it give error saying

Cannot invoke "java.lang.Integer.intValue()" because the return value of "java.util.Map.get(Object)" is null.



This is the same result when I used the entire code as it is (hashCode method not overridded and also when I overrided hashcode by returning fixed value 100 all time, which ofcourse is wrong).

Next, I tried to print and check the hashCode values for the two objects (one that was inserted in the map and the other that was used for retrieving) as below:




Output:

hashCode for personObj1->2088051243
Enter your name and age to find out how much you won!
hashCode for personObj2->93122545
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "java.util.Map.get(Object)" is null



So, the two objects are having different hashcode and we are not able to retrieve using it (as it is treating them as different objects as expected).


Next, I added the below code :



Result:

hashCode for personObj1->100
Enter your name and age to find out how much you won!
hashCode for personObj2->100
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "java.util.Map.get(Object) is null



Sensing that this may be due to hashcode, equals contract, I overrided equals too as below:



Result: The same as above.

Does the error mean that either the equals method was not overridden or it was overridden but not in the correct way?
thanks
 
Campbell Ritchie
Marshal
Posts: 79178
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Monica Shiralkar wrote:. . . Does the error mean that either the equals method was not overridden or it was overridden but not in the correct way?
thanks

Please, you tell us.
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks. In my opinion, the only possibility for this is that equals is not overridden correctly. I will check on how to correct that and try again.
 
Liutauras Vilda
Marshal
Posts: 8857
637
Mac OS X VI Editor BSD Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Monica Shiralkar wrote:Thanks. In my opinion, the only possibility for this is that equals is not overridden correctly. I will check on how to correct that and try again.


You are trying from the mechanics to understand how the HashMap (in this case) works. I'd first read HOW the hash tables work in general, then you'd understand the WHY about its mechanics.
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Liutauras Vilda wrote:

Monica Shiralkar wrote:Thanks. In my opinion, the only possibility for this is that equals is not overridden correctly. I will check on how to correct that and try again.


You are trying from the mechanics to understand how the HashMap (in this case) works. I'd first read HOW the hash tables work in general, then you'd understand the WHY about its mechanics.



Sure. But what exactly is deduced from the above exercise which I did?
 
Bartender
Posts: 5465
212
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There's a way to cheat Liutauras:
 
Only problem is when that person has become older when queriyng.
 
Liutauras Vilda
Marshal
Posts: 8857
637
Mac OS X VI Editor BSD Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Piet  

I on purpose said

Note: program is complete, except Line 20.


One more   see you in AoC
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Piet Souris wrote:There's a way to cheat Liutauras:
 
Only problem is when that person has become older when queriyng.



Thanks. But what exactly is deduced related to what I was seeking?
 
Liutauras Vilda
Marshal
Posts: 8857
637
Mac OS X VI Editor BSD Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Monica Shiralkar wrote:But what exactly is deduced related to what I was seeking?


Well, quite a lot you can deduct from Piet's example. i.e. that really without overriding hashCode() and equals() you lose almost all benefits what hash based data structure is offering you, because the only way (in my example) to figure out whether you have something in the map is iterate over the all keys, and that is a performance issue (O(n)), or actually the second way is to cary over along with prizes all the references you added to it, so later you could use them in some way for getting elements out of map - but that is also less than optimum way. How would you mange to cary across all of your program pieces all the references you have in a map(s)?

So how things worked for you initially without overriding hashCode() and equals(). Object's hash code helps to define to which hash table bucket the object should be stored. Since you are using to query map the exact same reference you added to it - it works, because the hash code doesn't change, and the equals implementation is not needed only because first it tries to check whether the references are exactly the same, in the hash table's bucket and the one you used calling Map.get() (and they are same, since you used the same reference for adding and querying), and if would turnout for whatever reason that references aren't equal, then equals() method would be used, however, even if you'd override equals() and not hashCode(), it is very likely the key you used in Map.get() would produce you a different hash code (unless collision would occur), which means it would look for reference in a wrong hash table's bucket, hence wouldn't find.

Now when you overrode hashCode() which returned a constant value 100, all references would have been stored in the same bucket within the hash table - super fast add, however, very slow retrieval, because presumably many references would be in the same bucket, O(1) to put elements, O(n) for retrieving them. While what you actually want to have for get operation is amortized O(1). Worst case of HashMap get is O(log n), it used to be O(n) I think before Java 7 or 8, but why not O(1) always? Will let you research why, but I already hinted in this post. Due to potential what?

So you really should be overriding hashCode() and equals() where you storing your data within hash based data structures. There are some niuances which I omitted in the post, but if they come up, we can elaborate more on those.
 
Liutauras Vilda
Marshal
Posts: 8857
637
Mac OS X VI Editor BSD Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Liutauras Vilda wrote:...why not O(1) always? Will let you research why, but I already hinted in this post. Due to potential what?


One more hint. In a form of two questions. These are probably classic questions.

1. If objects appear to be equal, do their hash codes must be equal too?
2. If hash codes are equal, do objects must be equal too?
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I got it working.

Output:

hashCode for personObj1->100
Enter your name and age to find out how much you won!
hashCode for personObj2->100
Prize money won by joe->1000000

Heres my complete code:



Thanks.
 
Liutauras Vilda
Marshal
Posts: 8857
637
Mac OS X VI Editor BSD Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Monica Shiralkar wrote:I got it working.

hashCode for personObj1->100


You shouldn't just blindly return 100 for hashCode. Research how that supposed to be implemented, or just generate implementation with your IDE and look how's done there.

Most importatly, answer to yourself whether you understand how hash based data structures work. Those two methods just sort of mechanisms to make certain things work as they should.

Have you got answers to those questions?

1. If objects appear to be equal, do their hash codes must be equal too?
2. If hash codes are equal, do objects must be equal too?

 
salvin francis
Bartender
Posts: 2911
150
Google Web Toolkit Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I would refer you to my code snippet above :
You just committed that crime !!
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

salvin francis wrote: You just committed that crime !!



Yes I knew hard coding like this cannot be a right way. But to get the code working I had done that. Let me correct it
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Liutauras Vilda wrote: or just generate implementation with your IDE and look how's done there.



That was so easy using Eclipse. All I had to do is right click and generate hashCode and equals and it gave below code:





1. If objects appear to be equal, do their hash codes must be equal too?
2. If hash codes are equal, do objects must be equal too?




1. If objects appear to be equal, do their hash codes must be equal too?  Yes
2. If hash codes are equal, do objects must be equal too?  Not necessary.
 
Campbell Ritchie
Marshal
Posts: 79178
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
And do you understand those implementations? Tell us what differences you may see if you useas opposed toorAlso tell us why I missed out two lines from the second example.

Remember that automatically generated code is exempt from style conventions, but you can reduce the multiple returns to one like this:-Tell me which error I didn't correct when I copied and edited that method.
Does it matter which order the subexpressions are evaluated in?
The () around the ?: expression (lines 16‑17) are not redundant.
Swings and roundabouts: you lose lots of returns but you gain two additional casts.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic