wood burning stoves 2.0*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes K&B Chapter 7, Self Test 5 Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "K&B Chapter 7, Self Test 5" Watch "K&B Chapter 7, Self Test 5" New topic
Author

K&B Chapter 7, Self Test 5

Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
K&B Chapter 7, Self Test 5
A. hashCode() doesn�t have to be overridden if equals() is
B. equals() doesn�t have to be overridden if hashCode() is
The authors say A and B are incorrect because by contract hashCode() and equals can�t be overridden unless both are overridden.
I think B is correct. One way to assign a unique integer to an object is the memory address of the object. But that is not the only way.
What do you think?
Maulin Vasavada
Ranch Hand

Joined: Nov 04, 2001
Posts: 1873
hi

One way to assign a unique integer to an object is the memory address of the object. But that is not the only way.

so how do u specify the "other way"? overriding hashCode() right? ie. u did override hashCode() to make it work with equals(). or do i sound stupid enough to get kicked on friday?
regards
maulin
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
Hi Maulin,
The Object API mentions that hash codes are typically implemented by converting the internal address of an object into an integer.
Suppose your hardware has a 16-bit word. Then the hash code is always in the range 0 to 2^16-1.
Suppose the HashSet algorithm assigns objects to buckets in the hashtable uniformly when the hash code is in the range of a Java integer, 0 to 2^32-1. By overriding the hashCode() method and multiplying by 2, you might get a more uniform distribution of objects in buckets.
However, there is no reason to override the equals method.
In general, you might want to redefine or modify the hash code definition provided by your virtual machine.
[ August 15, 2003: Message edited by: Marlene Miller ]
Maulin Vasavada
Ranch Hand

Joined: Nov 04, 2001
Posts: 1873
hi Marlene
i guess v 2 r talking about different things. i believe that the book author wants to refer to the case where we want to find "when two objects are equal?" and what you are referring to is- "how we can make hascodes uniformly distributed?" (or am i incorrect?).
if we consider equality of two objects then author's suggestion is right. we have to override both hashCode() and equals() to be consistent according to Object API's equals() method.
i agree what u r saying but i doubt if author is pointing in same direction as u r and i guess thats what is the confusion.
regards
maulin
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
Thank you Maulin for your explanation.
Bert Bates
author
Sheriff

Joined: Oct 14, 2002
Posts: 8883
    
    5
Marlene -
I think I agree with Maulin, but just to be sure let me ask a you a question:
Are you worried about:
1) Whether certain hashCode() algorithms will be efficient ?
-or-
2) Whether your class's objects can be sucessfully stored and retrieved from collections that use hashing ?
- Bert


Spot false dilemmas now, ask me how!
(If you're not on the edge, you're taking up too much room.)
Bert Bates
author
Sheriff

Joined: Oct 14, 2002
Posts: 8883
    
    5
dang, I hate not being able to delete mistakes!! :roll:
[ August 15, 2003: Message edited by: Bert Bates ]
Alton Hernandez
Ranch Hand

Joined: May 30, 2003
Posts: 443

Originally posted by Maulin Vasavada:

if we consider equality of two objects then author's suggestion is right. we have to override both hashCode() and equals() to be consistent according to Object API's equals() method.

Isn't it that when it comes to equality, the main consideration is that objects must produce the same hashCode() value in order to be considered equal (and of course the equals() method must return true and all those transitive, reflexive thing). So if we are just considering equality, then overriding hashCode() may be enough.
Consider the code below:

The class A6 wants to stick to the equals() definition of the Object method i.e. to be equal they have to point to the same reference. So A6 only modified the hashCode() method (which is not very efficient) but not the equals() method.
Now I would assume that this is OK because it managed to keep the contract. So If you could find a much better hashing algorithm (perhaps to store the objects much more efficiently in a Collection), then as long as you can keep the contract, modifying the hashCode() alone should be enough.
Any comments?
[ August 15, 2003: Message edited by: Alton Hernandez ]
Anupam Sinha
Ranch Hand

Joined: Apr 13, 2003
Posts: 1088
Hi All
Please explain now why option A is incorrect.
Bert Bates
author
Sheriff

Joined: Oct 14, 2002
Posts: 8883
    
    5
Let's try this...
What if you want to use instances from your class as keys in a HashMap, and you want a hashing algorithm that allows multiple entries in a single 'hash bucket'.
1 - You override hashCode(), and now sometimes you get multiple entries in a single bucket.
2 - You put an object into a HashMap and your key is a particular Dog object. Let's say that because of your overridden hashCode(), several Dog object keys are now in the same bucket.
3 - Later on you want to retrieve that entry from the HashMap, but you haven't overridden equals(). The only way to do a sucessful get() is if you happen to still have a reference to the original Dog object. You can't create a new Dog object that will be 'equals()' to the old Dog object, unless you've overridden the equals() method. This is because the default equals() method uses == under the covers and for objects, == compares to see if the ref. vars. are referring to the same object, it doesn't care if the objects have the same state.
So the get() method goes to the bucket using the hashcode, then once it's in the right bucket it uses the equals() method to find the right object.
does that make any sense?
Alton Hernandez
Ranch Hand

Joined: May 30, 2003
Posts: 443
Hi Bert,
I agree that in your scenario, you will be faced with a dilema.
But assuming that there is a class that satisfies your requirement for equality() but NOT its hashCode() function. If you were to exend this class and override its hashCode() function(assuming again that it will return the same value for objects that are considered equal), is it necessary to replace the equals() method as well? When we say that we must override both equals() and hashCode() method, is this more of a guideline than a necessity?
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
Thank you Bert for considering my question.
Whether certain hashCode() algorithms will be efficient ? Whether your class's objects can be sucessfully stored and retrieved from collections that use hashing?

No (or marginally Yes). No. Here is what I am thinking.
1. Is it possible to override only hashCode() and be sure that objects which are equal() have the same hashCode()?
Yes. For example, take the result from Object.hashCode() and add 1. For example, any mapping on the set of 32-bit two�s complement integers that is 1-to-1 will also work.
2. Is there a good reason to override only hashCode()?
Maybe you don�t like the hashCode values that your virtual machine generates. Why not?
I got this idea from K&B Chapter 7, Self Test 2. I wanted to know the effect of i^5. So I wrote out the first 8 numbers.
000^101 == 101, 0 -> 5
001^101 == 100, 1 -> 4
010^101 == 111, 2 -> 7
011^101 == 110, 3 -> 6
100^101 == 001, 4 -> 1
101^101 == 000, 5 -> 0
110^101 == 011, 6 -> 3
111^101 == 010, 7 -> 2
Notice how the mapping redistributes the 8 numbers.
Maybe by using an exclusive OR transformation, you could get a better distribution of objects to buckets. Such a transformation does not require overriding the equals method. The objects are still equal() if and only they are ==.
Point 1. above is what I care about. Point 2. is how I got to 1.
[ August 15, 2003: Message edited by: Marlene Miller ]
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
Alton, thank you for your ideas. In my opinion, mapping all objects to the same integer is a little extreme. I was just thinking about shuffling the integers.
Alton Hernandez
Ranch Hand

Joined: May 30, 2003
Posts: 443
Originally posted by Marlene Miller:
In my opinion, mapping all objects to the same integer is a little extreme. I was just thinking about shuffling the integers.

Hi Marlene,
I just want to drive my point about the contracts.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: K&B Chapter 7, Self Test 5