Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Equals and HashCode

 
avihai marchiano
Ranch Hand
Posts: 342
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey,

I know that this is the most popular discussion, so sorry for raise it again.

In my application the objects are equals if they are equals in all the fields (except ID).

So few questions:
1. Do i need to check equals on all the fields include references, collections and etc.
I looks on equals example and didnt saw that reference and collection was compared, what is the reason for this? lets say i have a user that has a reference to an Address . the users are not equals if the address that they point is not equal.

2. Lets say i have class B that inherit from A class B has no primitive fields (only additional references) how the equals of B need to look like ?
What about B - hashCode function (is not seem resonable to call to super in the hashcode) ?

Thank you
 
Shailesh Kini
Ranch Hand
Posts: 153
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Avihai,

Q1. If your check of equals should satisfy all primitive fields, object references and collections then you will have to check for everything. Checking equals on primitive fields is very straight forward. However for the references you will have to override equals method for each of those references. To check equality you can call equals on each of the refernces.

In your example, you will have to override equals method for both User and Address. Address should check the equality of various fields. In the User's equals methods you will have to check for equality on user fields and also call equals() on address object.

Q2. Class A will override equals method and provide check for equality of all its fields. Class B can call super.equals in addition to calling equals on the additional references it has.

You might have to override hashcode depending on how you have implemented it. If your hashcode is calculated based on each of the field values in A, you might have to override it in B to also include hashcode of references.

Consider the scenrio where you have 2 B objects and all the values in its super class are the same but the references they contain are different. In this scenario if you do not override hashcode then these 2 objects will be stored in the same bucket. This will make collection searches slower.

Hope this helps.
 
avihai marchiano
Ranch Hand
Posts: 342
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What are you doing in your application?

It seems to much to check all the object graph for equals,
but it also seems insufficent to chek only object field without check his references.

Thank you
 
Nitesh Kant
Bartender
Posts: 1638
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is what the javadoc for equals method says:

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.


So, whenever you change the default behavior of equals() method(i.e. two references are equals if they refer to the same object instance) then you *should* override hashcode also.

Implementation of equals depends on what are the rules for equality of the object in question. If you require every field to be included for equality check then you have to do that. There is no best practice as such.
 
avihai marchiano
Ranch Hand
Posts: 342
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yep, I know that.

My question is about best practice to equals.

As i wrote-

It seems to much to check all the object graph for equals,
but it also seems insufficent to chek only object field without check his references.

So, i wonder what other does
 
Shailesh Kini
Ranch Hand
Posts: 153
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Avihai,

If you want to implement something generic then you will have to use visitor pattern to traverse through the object hierarchy recursively and use reflection to get the referenced entity and call equals on them. To include only certain object references in your equals check you could mark them with a marker interface or custom annotation.

If you are interested in optimistic locking features, you should look into using @Version annotation. This will however not stop updates when no changes have been made to the data.
 
avihai marchiano
Ranch Hand
Posts: 342
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks a lot for your answer.

Maybee i was not clear.

ORM required that you implement equal.

You can write the equal based on the version or the orm id because one of the objects (or both) is transetive, so it dosnt has orm id , but it equal to the other object (which was already saved).

Lets discuss on the example i gave. As i understand equal the user is not equal to the other user if the address that they point to it is not the same,

But i saw a lot of java code exapmles and no one check the reference in the equal.

Why?
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic