Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / January 2006

Tip: Looking for answers? Try searching our database.

In 'HashMap.put',  "if (e.hash == hash && eq(k, e.key))" ?

Thread view: 
Red Orchid - 30 Jan 2006 11:43 GMT
The 'HashMap.put' has the code "if (e.hash == hash && eq(k, e.key))".
Do you think that the 'e.hash == hash' is required ?

I think that the "if (k == e.key || k.equals(e.key))" is proper.

For further details,
the following codes are parts of 'HashMap'.

<code>
public V put(K key, V value) {
   K k = maskNull(key);
   int hash = hash(k);
   int i = indexFor(hash, table.length);

   for (Entry<K,V> e = table[i]; e != null; e = e.next) {
       if (e.hash == hash && eq(k, e.key)) {  // #1
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
       }
   }
   ...

static int indexFor(int h, int length) {
   return h & (length-1);   // #2
}

static boolean eq(Object x, Object y) {
   return x == y || x.equals(y); // #3
}

</code>

The linked list of the 'table[i]' is heterogeneous with
hash value.  That is, when hash value of 'E0' is 5
and one of 'E1' is 6, both 'E0' and 'E1' can exist in
the same bucket 'table[i]' because of the above #2
( 00 & 10 = 00, 01 & 10 = 00).

But, it do not justify the code "if (e.hash == hash" of #1.

Because, ...

a) The functions of 'Map' puts/gets the value 'V' that is
mapped by the key 'K', not by the hash value.

b) The execution time of "k == e.key" by #3 is not large
than one of 'e.hash == hash'.

Therefore, I think,
The code "if (k == e.key || k.equals(e.key))" is proper
instead of #1.  #1 is overabundance.

I think that if there is overabundance in a library,
it means that the library is not optimised.

What is your opinion ?
Thanks.
Hendrik Maryns - 30 Jan 2006 12:19 GMT
Red Orchid schreef:
> The 'HashMap.put' has the code "if (e.hash == hash && eq(k, e.key))".
> Do you think that the 'e.hash == hash' is required ?
[quoted text clipped - 54 lines]
>
> What is your opinion ?

I definitely agree that the code could be much clearer, but in a hurry
(and after some debugging experience with disappearing values), I am
pretty sure I can tell you that this test is to make sure that different
keys that give the same hash code can still be stored, that is what the
linked list is for.

H.

- --
Hendrik Maryns

==================
www.lieverleven.be
http://aouw.org
Gordon Beaton - 30 Jan 2006 13:03 GMT
> The 'HashMap.put' has the code "if (e.hash == hash && eq(k,
> e.key))". Do you think that the 'e.hash == hash' is required ?

The extra test is an optimization for a common case, since it is a
fast operation compared to invoking equals() on each of the keys.

Each bucket in the hastable can potentially store many different
objects with different keys and different hash values. There is no
point in checking the key for equality unless you know the hash value
is correct.

> I think that the "if (k == e.key || k.equals(e.key))" is proper.

k == e.key implies k.equals(e.key), so both tests aren't strictly
necessary.

However k.equals(e.key) does not imply k == e.key, so you need to
check with equals() regardless for those times when a different key
(with the same value) is used.

Your test for identity (k = e.key) might give a slight performance
advantage when identical (not just equal) keys are being reused often,
but likely less than the hash comparison above.

/gordon

Signature

[  do not email me copies of your followups  ]
g o r d o n + n e w s @  b a l d e r 1 3 . s e

zero - 30 Jan 2006 19:04 GMT
>> The 'HashMap.put' has the code "if (e.hash == hash && eq(k,
>> e.key))". Do you think that the 'e.hash == hash' is required ?
>
> The extra test is an optimization for a common case, since it is a
> fast operation compared to invoking equals() on each of the keys.

Remember that that && operator shortcuts - it doesn't evaluate the second
operand if the first is already false.  So, provided the elements have good
hashing algorithms, this can indeed have quite some influence on
performance.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.