Collision in hashmap

≯℡__Kan透↙ 提交于 2021-01-28 06:30:53

问题


I have read about the Hashmap collision and took the following example. Since i am not able to understand what is collision and how to avoid collision is occurs. The example is follows

import java.util.*;  
class JavaCollision{  
public static void main(String args[]){  

 HashMap<Person, String> map=new HashMap<Person, String>();
 Person p1 = new Person(1,"ABC");
 Person p2 = new Person(2,"DEF");
 Person p3 = new Person(1,"XYZ");
 Person p4 = new Person(1,"PQR");
 Person p5 = new Person(1,"PQR");
 System.out.println("Adding Entries ...."); 
 map.put(p1,"ONE");
 map.put(p2,"TWO");
 map.put(p3,"THREE");
 map.put(p4,"FOUR");
 map.put(p5,"FIVE");

 System.out.println("\nComplete Map entries \n" + map);

/* System.out.println("\nAccessing non-collided key");  
 System.out.println("Value = "+map.get(p2));
 System.out.println("\nAccessing collided key");    
 System.out.println("Value = " + map.get(p1));*/
 System.out.println("P1 hashcode is:"+map.get(p1).hashCode()+" And value is:"+map.get(p1));
 System.out.println("P2 hashcode is:"+map.get(p2).hashCode()+" And value is:"+map.get(p2));
 System.out.println("P3 hashcode is:"+map.get(p3).hashCode()+" And value is:"+map.get(p3));
 System.out.println("P4 hashcode is:"+map.get(p4).hashCode()+" And value is:"+map.get(p4));
 System.out.println("P5 hashcode is:"+map.get(p5).hashCode()+" And value is:"+map.get(p5));
}
}  

Person.java

public class Person {
private int id;
private String name;

public Person(int id, String name) { 
    this.id = id; this.name = name;
}

public String getName() { 
    return name;
}

public int getId() { 
    return id;
}

public void setId(int id) { 
    this.id = id;
}

public void setName (String name) { 
    this.name = name; 
}

public int hashCode(){
    System.out.println("Called hashcode for:"+id+" - "+name);
    return id;
}

public boolean equals(Object obj){
    System.out.println("Called equals on ="+id+" - "+name+" to compare with "+((Person)obj));
    boolean result=false;
    if(obj instanceof Person){
        if( ((Person)obj).getId() == id  && ((Person)obj).getName().equals(name) ){
            result=true;
            System.out.println("Result is true");
        }
    }
    return result;
}
public String toString() { 
    return id+" . "+name;
} 
}

And the result is

Adding Entries ....
Called hashcode for:1 - ABC
Called hashcode for:2 - DEF
Called hashcode for:1 - XYZ
Called equals on =1 - XYZ to compare with 1 . ABC
Called hashcode for:1 - PQR
Called equals on =1 - PQR to compare with 1 . ABC
Called equals on =1 - PQR to compare with 1 . XYZ
Called hashcode for:1 - PQR
Called equals on =1 - PQR to compare with 1 . ABC
Called equals on =1 - PQR to compare with 1 . XYZ
Called equals on =1 - PQR to compare with 1 . PQR
Result is true

Complete Map entries 
{1 . ABC=ONE, 1 . XYZ=THREE, 1 . PQR=FIVE, 2 . DEF=TWO}
Called hashcode for:1 - ABC
Called hashcode for:1 - ABC
P1 hashcode is:78406 And value is:ONE
Called hashcode for:2 - DEF
Called hashcode for:2 - DEF
P2 hashcode is:83500 And value is:TWO
Called hashcode for:1 - XYZ
Called equals on =1 - XYZ to compare with 1 . ABC
Called hashcode for:1 - XYZ
Called equals on =1 - XYZ to compare with 1 . ABC
P3 hashcode is:79801726 And value is:THREE
Called hashcode for:1 - PQR
Called equals on =1 - PQR to compare with 1 . ABC
Called equals on =1 - PQR to compare with 1 . XYZ
Called hashcode for:1 - PQR
Called equals on =1 - PQR to compare with 1 . ABC
Called equals on =1 - PQR to compare with 1 . XYZ
P4 hashcode is:2158258 And value is:FIVE
Called hashcode for:1 - PQR
Called equals on =1 - PQR to compare with 1 . ABC
Called equals on =1 - PQR to compare with 1 . XYZ
Called equals on =1 - PQR to compare with 1 . PQR
Result is true
Called hashcode for:1 - PQR
Called equals on =1 - PQR to compare with 1 . ABC
Called equals on =1 - PQR to compare with 1 . XYZ
Called equals on =1 - PQR to compare with 1 . PQR
Result is true
P5 hashcode is:2158258 And value is:FIVE

In this result p4 and p5 having same hashcode. How to avoid the same hashcode using in hashmap. Can we able to avoid the collision by returning hashcode.


回答1:


You have a weird understanding of what collision in a HashMap is. It is actually pretty simple - it's when two objects have the same hashcode after the internal re-hashing is done inside a HashMap:

static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

Basically after you compute the hashcode, HashMap will take the first 16 bits and XOR those with the last 16 bits - the ensure better distribution. If, after this re-hashing, two different keys have the hashcode value - this is called a hash collision. This means that two entries will end-up in the same bucket.

But generally this is ever a performance bottleneck, as entries that are placed in the same bucket (after they reach a certain number) are put into a perfectly balanced red-black tree, and the search is still very fast. For example if there are 2 pow 32 entries in this bucket, it will take max 32 steps to find this entry; the general search time being O(logn) in this Tree bucket. And for the map itself the search time would be O(1) - constant.

So don't complicate yourself - while you could test your Key#hashCode so that it has a better hashcode - don't do that, unless you are sure that there is a performance issue (which I highly doubt).




回答2:


In this result p4 and p5 having same hashcode.

Correct, but that's not the issue here. The issue is that p4 and p5 have the same key, i.e. the value of id. A Map doesn't contain duplicates, so p4 was overwritten by p5, because they have the same id, not just the same hashcode.

How to avoid the same hashcode using in hashmap.

There is no need to avoid collisions in HashMaps, and that isn't the problem here.

Can we able to avoid the collision by returning hashcode.

Yes, but that's not the issue here. If you want both p4 and p5 in this map, you will have to give them different keys. What that means in this case is that as your equals() method is based on both id and name, so should your hashCode() method be:

public int hashCode()
{
    return id+name.hashCode(); // for example
}


来源:https://stackoverflow.com/questions/45952231/collision-in-hashmap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!