Win a copy of Microservices Testing (Live Project) this week in the Spring forum!
  • 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
  • Tim Cooke
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Liutauras Vilda
  • Henry Wong
  • Devaka Cooray
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Al Hobbs
  • Carey Brown
Bartenders:
  • Piet Souris
  • Mikalai Zaikin
  • Himai Minh

hash code and final

 
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I cannot understand why the value of a final field should be excluded from a hash code computation.
This is from a mock exam explanation:
private int length;
private int width;
private final double area;
Also, the fact that �area� is a final variable indicates that its value cannot be changed later. Hence it should not be included in the computation of the hash code value for the objects of this class.
[ September 24, 2003: Message edited by: Marlene Miller ]
 
Ranch Hand
Posts: 787
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Also, the fact that �area� is a final variable indicates that its value cannot be changed later. Hence it should not be included in the computation of the hash code value for the objects of this class.


I would agree with this statement if area is being assigned by an instance initializer in following manner
class Test{
final double area = 50;
}
Now area will be same for all instances. As hashcode is supposed to reflect the uniqueness of a particular instance, including area in hashcode algorithim will not help much.
However, if area is being assigned in a constructor like:
class Test {
double length, width;
final double area;
Test(int length, int witdth) { area = length * width ; }
}
Now area is different for each instance and hence it is a good variable to include in hashcode algorithm.
Thanks
Barkat
 
Ranch Hand
Posts: 504
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It is strange Marlene because as we know returning int literals as objects hash codes is perfectly legal and even appropriate not violating the joint contract. To me, a final variable means almost the same as a literal compile time constant.
 
Barkat Mardhani
Ranch Hand
Posts: 787
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thinking more about it. I think fact that area is final has no bearing on its appropriateness for inclusion in hashcode calculations. It is the degree of its variance from one instance to other.
I would say given explaination is misleading.
 
Vad Fogel
Ranch Hand
Posts: 504
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I beleive using finals for hash code is legal yet not being of much help for search speed. Does the explanation say that finals must be excluded from hash calculations?
 
Barkat Mardhani
Ranch Hand
Posts: 787
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
posted by Vad:

I beleive using finals for hash code is legal yet not being of much help for search speed. Does the explanation say that finals must be excluded from hash calculations?


Hi Vad,
Note 'final' does not neccessarilly mean that it is 'same' for all instance. It simply means it can not be changed. Wether all instances have same area or not depends on how it is being assigned as I explained in my post above. If it is same for all instances, it's inclusion in hashcode calculation will make hashcode ineffecient.
Thanks
Barkat
 
Vad Fogel
Ranch Hand
Posts: 504
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, I guess efficiency of the hash code is kinda luxury we can rarely afford.
I'm trying to figure out if it's legal at all to use finals in hash code calculation, and in my opinion, there's nothing to hold us back from doing it. I know of one case when hashing can fail and it's using transient variables, but still legal. What do you think?
[ September 24, 2003: Message edited by: Vad Fogel ]
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Marlene, where did you hear that finals should be excluded from hashcode computations? I'm guessing that wherever it was, they really meant final static fields. If a value is the same across the entire class, it probably isn't very useful for the hashcode. Though it may be in some circumstances, e.g. where your HashMap has objects from a lot of different classes. Or even more unlikely scenarios. In general though I'd agree with those who say that whether a field is final should probably be ignored when computing hash codes. Actually, immutable objects are often better has map keys anyway, since if someone changes a mutable field, that will change the hash code, which changes where the key shoul be found in the internal hashmap structure, exceptthat most likely the HashMap won't actually recompute the hashCode() since it just assumes that the hashCode() will remain constant... You can avoid this by making a point of not changing objects which are used as keys, to avoid this confusion. But it's worthwhile to try using immutable objects as your keys in the first place.
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Barkat, Vad and Jim for your very helpful explanations. Now I will try to synthesize what I am tring to understand.
The desired goal is to produce unequal hash codes for unequal objects.
The desired goal is to distribute the keys of hash map.
In general, every instance field that is used in the equality comparison should be used in the hash function.
1. final int x = 10;
We know that a final field whose initializer is a constant expression is a compile-time constant. Such a field is not useful in the hash function.
2. final int y;
A blank final field is not a compile-time constant. In general, there is no reason to exclude it from the hash function.
Have I got it right?
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Vad, the mock exam wants to know the most appropriate implementation of the hashCode() method, not whether it is a legal implementation.
Is there some reason to exclude a transient field?
 
Vad Fogel
Ranch Hand
Posts: 504
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Marlene,
I've read K&B on hashing, but unfortunately, I didn't get the difference between legal and appropriate implementation from there. For instance,
is considered not only legal, but also an appropriate hash code implementation. It's not efficient though. I thought that legal means not violating the joint contract for equals() and hashCode(), and appropriate is... well, kind of effective, but it's obviously not so.
As for transient fields used for hashing, they can cause some pain on deserializing an object because they are not serialized and therefore come back zeroed, so the same object now exposes a different hashCode from when it'd been serialized, and hashing is screwed up.
 
Barkat Mardhani
Ranch Hand
Posts: 787
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
posted by Jim:

Marlene, where did you hear that finals should be excluded from hashcode computations? I'm guessing that wherever it was, they really meant final static fields. If a value is the same across the entire class, it probably isn't very useful for the hashcode. Though it may be in some circumstances, e.g. where your HashMap has objects from a lot of different classes. Or even more unlikely scenarios. In general though I'd agree with those who say that whether a field is final should probably be ignored when computing hash codes. Actually, immutable objects are often better has map keys anyway, since if someone changes a mutable field, that will change the hash code, which changes where the key shoul be found in the internal hashmap structure, exceptthat most likely the HashMap won't actually recompute the hashCode() since it just assumes that the hashCode() will remain constant... You can avoid this by making a point of not changing objects which are used as keys, to avoid this confusion. But it's worthwhile to try using immutable objects as your keys in the first place.


Thanks Jim for this informative note. It makes sense to use immutable objects as your keys. But hashcode contract does not mention that it is required to use only final fields for calculating hashcode. Per your point that HashMap will not recompute the hashCode() if relevant fields change. Will that not cause errors in programs?
Thanks
Barkat
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic