开发者

putiing objects to hash based collection

Suppose I have the below class.

class S{

String txt = null;

S(String i){
txt=i;
}

public static void main(String args []){
S s1 = new S("a");
S s2 = new S("b");
S s3 = new S("a"); 

Map m = new HashMap ();
m.put(s1, "v11");
m.put(s2, "v22");
m.put(s3, "v33");

System.out.println(m.size());   
}

//just a plain implementation
 public boolean equals(Object o)
 {
     开发者_JS百科 S cc = (S) o;
      if (this.i.equals(cc.i))
      {    
         return true;
      }
      else
      {
         return false;
      }    
   }

   public int hashCode()
   {
      return 222;
   }  

}

This will return size as 2 when running above. Its totally fine. If we comment the hashCode() it return 3 which is also correct. But if we comment the equals and keep the hashCode it should return 2 right? instead it returns 3. When putting objects to hashmap map will check the hash code of an object and if its same it will replace the previous value of the map to the new one right?

Thank You.


But if we comment the equals and keep the hashCode it should return 2 right? instead it returns 3.

3 items is the correct behaviour. 3 objects will be hashed to the same bucket, but because all 3 are different this bucket will contain a chain of values (linked list for HashMap in Java) with the same hash code but not equal to each other.

When putting objects to hashmap map will check the hash code of an object and if its same it will replace the previous value of the map to the new one right?

If they are hashed to the same bucket it doesn't mean that one value will replace another. Then these values will be compared for equality. If they are equal then old value will be replaced, if they are not - new value will be added to the tail of the linked list (for this bucket).


The hashcode is simply used to determine the bucket in which to place the object. Each bucket can contain more than once object. So hashcode must be implemented to ensure that equal objects go in the same bucket. In other words equal objects must have the same hashcode but objects with the same hashcode aren't necessarily equal.


When you override only hashcode nothing really changes. You are just putting every object in the same bucket with return 222. So the HashMap is more inefficient, but its contract doesn't change.


The hashcode is the first, quick method to find if two objects are equal or not. It is used by hash containers to decide in which "slot" the object may go, and to retrieve it without checking for all of the objects in all of the slots.

If your hashcode is always the same, then all the objects will be directed to the same slot. This is called collision. Insertions will be slower, because after the collision the container will have to check if the objects already in that slot match the new one (equals). Also, retrieval will be slower because it will have to check all of them sequentially until it finds the right one(equals againg). Finally, probably there will be a lot of unused memory wasted in slots that will not be used.

In essence, by no implementing a sensible hashcode you are converting the hashcontainers in lists (and inefficient ones).


If we comment the hashCode() it return 3 which is also correct.

This is not correct! There are only 2 different objects: "a" and "b". The equals method says what is equal and what is not. The expected size is 2. But, because the equals-hashcode contract is broken, the returned size is 3.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜