harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paulex Yang <paulex.y...@gmail.com>
Subject Re: [classlib]bug-to-bug compatibility: HashMap
Date Thu, 16 Mar 2006 09:54:29 GMT
Hi, Mikhail,

Mikhail Loenko wrote:
> Hi Paulex,
>
> IMHO from compatibility point of view any behavior is legal.
> HashMap is mostly designed for keys that do not change over time, at least
> spec silent about changing the keys. So, I think implementation specsific is
> allowed here.
>
> But I think that aiming stability we'd better compare current hash
> with the original one - in this case get() result will depend on the hash
> rather that on the inernal state of HashMap (such as HashMap length)
>   
I'm afraid the problem here is not the HashMap length,  whatever the 
length is, this kind of problem can happen, 16 just make it more easier, 
because it is not a prime number.

So if my understanding is right, you suggest to cache the key's hash 
value as *original* hash into HashMap.Entry, when the key/value pair is 
put into HashMap; and when someone want to get back the value from 
HashMap by the same key, the cached *original* hash will be compared 
with the *current* hash, and if they are not equal, HashMap will 
consider them as non-match, even the keys are *same* object. In fact 
that's also my point of view to fix this non-compatibility. This fix is 
not difficult, but the only concern is, this behaviour may be 
controversial.

thoughts?
> Thanks,
> Mikhail
>
> 2006/3/15, Paulex Yang <paulex.yang@gmail.com>:
>   
>> Pls. try the test case on HashMap below.
>>
>> On RI, it print out:
>> null
>> null
>>
>> On Harmony, it print out
>> null
>> value1
>>
>> it is definitely bad practice to reuse a object as hash key by modify
>> its hashcode, but I DID see some similar cases before, after all, you
>> cannot force but only can *suggest* developers what to do.
>>
>> So, what should we do?  Try to replicate RI's behavior?
>>
>>
>> public class HashMapTest {
>>  public static void main(String[] args) {
>>  ReusableKey k = new ReusableKey();
>>  HashMap map = new HashMap();
>>  k.setKey(1);
>>  map.put(k, "value1");
>>
>>  k.setKey(18);
>>  //both RI and Harmony get null here
>>  System.out.println(map.get(k));
>>
>>  k.setKey(17);
>>  //RI get null
>>  //Harmony get "value1"
>>  //the number of 17 is *magic* because the default length of HashMap is 16.
>>  System.out.println(map.get(k));
>>  }
>> }
>>
>> class ReusableKey{
>>  private int key = 0;
>>  public void setKey(int key){
>>  this.key = key;
>>  }
>>  public int hashCode(){
>>  return key;
>>  }
>>  public boolean equals(Object o){
>>  if(o == this){
>>   return true;
>>  }
>>  if(!(o instanceof ReusableKey)){
>>   return false;
>>  }
>>  return key == ((ReusableKey)o).key;
>>  }
>> }
>>
>>
>> --
>> Paulex Yang
>> China Software Development Lab
>> IBM
>>
>>
>>
>>     
>
>   


-- 
Paulex Yang
China Software Development Lab
IBM



Mime
View raw message