• Post Reply Bookmark Topic Watch Topic
  • New Topic

Equals and Hashcode  RSS feed

 
raja singh kumar
Ranch Hand
Posts: 189
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I am trying to print a practical example of when equals method is called and when hashcode method is called. Is it not true that entries where the hashcode is equal go to same bucket and while retrieving the equals method is called? Why is the equals method not called when I am getting the object corresponding to e1 in the map but the equals method gets called when the e2 object is got?

Thanks in advance for your help

Employee1Test.java


Output:
first operation
hashcode called with name:suraj and length:5
second operation
hashcode called with name:sandy and length:5
equals called with this name as :sandy and employee name:suraj
Is it equal:true
third operation
hashcode called with name:sunny and length:5
equals called with this name as :sunny and employee name:suraj
Is it equal:true
fourth operation
hashcode called with name:suraj and length:5
fifth operation
hashcode called with name:sandy and length:5
equals called with this name as :sandy and employee name:suraj
Is it equal:true










 
Andrea Binello
Ranch Hand
Posts: 62
5
Eclipse IDE Java Spring
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
raja singh kumar wrote:Is it not true that entries where the hashcode is equal go to same bucket and while retrieving the equals method is called?

With hash-table based collections like HashMap/Hashtable, the equals/hashCode methods are used in the following way:

The collection contains a list of "buckets". Physically it's generally an array. The hashCode() of the key is used to direct to a single bucket. Under the bucket there is a list (typically a linked list) of entries, each composed of a key-value pair. At this point the collection must scan the list and find the key. To do this, the collection uses the equals() on the keys found in the list. If the key is found, the value of the entry is updated. If at the end the key is not found, a new entry is added.
 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I know I am late to the party, but your equals() method is incorrect. It must accept arguments of any reference type and nulls. If you pass a different type, the cast will produce an Exception, and if you pass null, that will also cause an Exception to be thrown.
 
raja singh kumar
Ranch Hand
Posts: 189
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I did not get you. The equals method is the way of saying when two employee objects are to be considered equal. For that I have casted  to Employee. What is wrong with that?

I got your null point. I need to check for null before calling methods of the Employee object
 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
raja singh kumar wrote:. . . I have casted  to Employee. What is wrong with that? . . .
As it stands, everything. It accepts Object; you must be able to pass any kind of Object as an argument. You shou‍ld also be able to deal with an Employee argument with name being null.

Have you not read any of the standard resources about equals? What about the Java™ Tutorials? Or Joshua Bloch's Effective Java? Or Odersky Spoon and Venners? Or Angelika Langer?
 
Carey Brown
Saloon Keeper
Posts: 3309
46
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In your links I found their discussion of instanceof vs getClass() to be interesting. My take-away was that you should pretty much use the getClass() approach unless you specifically designing a class where you intend subclasses to be tested against the super-class for equality. And, even then tread cautiously. I've been using getClass() a long time but I still found the write up to be illuminating.
 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A lot of people incline towards instanceof. The problem with getClass() is that subclass instances, even those of anonymous classes, will always return false from that test. The problem with subclasses is that people try to add fields and then use them in equals(). That is liable to break the symmetry or transitivity properties of the general contract of equals().

OP: I presume you know there are seven things to take into consideration to maintain the general contract for equals(). You override equals(), because most classes calling it call it on Object, so an overloaded version will be ignored. That is why you must override equals(), rather than overloading it.
Those seven things are:-
  • 1: You must also override hashCode(). Then there are six bullet points. I know you can only see five things there, but I can see six.
  • 2: Reflexivity: Every object is equal to itself.
  • 3: Symmetry. If object 1 is equal to object 2 then object 2 is equal to object 1, and vice versa if they are not equal.
  • 4: Transitivity: If object 1 is equal to object 2 and object 2 is equal to object 3, then object 1 is equal to object 3.
  • 5: Consistency. You always get the same result if nothing else changes.
  • 6: Non‑nullity. An object which exists is implicitly different from an object which doesn't exist.
  • 7: Now for No 7, which you can't see. It says you always get the same result (No 5), and you get false if you pass null (No 6). If you always get those results, then you mustn't throw an Exception. The only way you shou‍ld have an Exception thrown is if you call the method on the left operand being null.
  • The bullet points are really easy to understand, and really difficult to implement correctly.

    The problem about equals() is that there are three possible actions people want to do with subclasses.
  • 1: Maintain the general contract for equals().
  • 2: Use additional fields in subclasses.
  • 3: Maintain the Liskov Substitution Principle (LSP).
  • Now, I know you can go to the bar and have some beer (as I am doing now ), and hear somebody say, “Two out of three isn't bad,” but in this case it isn't true. It has never proven possible to fulfil all those three things. You have to abandon one of those three things; you will see problems about trying to maintain all three in the links I posted earlier. The only thing you can miss out without breaching the general tenets of object‑oriented programming is No 2, additional fields. If you have additional fields, you cannot use them in equals(). You can try the Collections Framework classes with tiny errors in your equals() method, and see how they go wrong.
    You shou‍ld find a solution in the links. You can make the equals() method final, as do enumerated types, or you can have a policy prohibiting additional fields in subclasses of types declaring an equals() method. Or you can do what the links say:-
    Favour composition over inheritance.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!