harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Richard Liang <richard.lian...@gmail.com>
Subject Re: [classlib]bug-to-bug compatibility: HashMap
Date Thu, 16 Mar 2006 14:42:26 GMT
Hello Paulex,

According to Java 5 Spec, "Note: great care must be exercised if mutable 
objects are used as map keys. The behavior of a map is not specified if 
the value of an object is changed in a manner that affects equals 
comparisons while the object is a key in the map...."

As the behavior of a map is not specified, we can either keep compatible 
with RI, or leave it as is. But keeping compatible with RI may be a 
better solution. :-)

Paulex Yang wrote:
> 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
>>>
>>>
>>>
>>>     
>>
>>   
>
>


-- 
Richard Liang
China Software Development Lab, IBM



Mime
View raw message