Java HashMap detect collision

前端 未结 3 1700
你的背包
你的背包 2021-02-06 01:00

Is there a way to detect collision in Java Hash-map ? Can any one point out some situation\'s where lot of collision\'s can take place. Of-course if you override the hashcode fo

3条回答
  •  庸人自扰
    2021-02-06 01:49

    The other two answers I see a good IMO but I just wanted to share that the best way to test how well your hashCode() behaves in a HashMap is to actually generate a big number of objects from your class, put them in the particular HashMap implementation as the key and test CPU and memory load. 1 or 2 million entries are a good number to measure but you get best results if you test with your anticipated Map sizes.

    I just looked at a class that I doubted its hashing function. So I decided to fill in a HashMap with random objects of that type and test number of collisions. I tested two hashCode() implementations of the class under investigation. So I wrote in groovy the class you see at the bottom extending openjdk implementation of HashMap to count number of collisions into the HashMap (see countCollidingEntries()). Note that these are not real collisions of the whole hash but collisions in the array holding the entries. Array index is calculated as hash & (length-1) which means that as short the size of this array is, the more collisions you get. And size of this array depends on initialCapacity and loadFactor of the HashMap (it can increase when put() more data).

    At the end though I considered that looking at these numbers does little sense. The fact that HashMap is slower with bad hashCode() method means that by just benchmarking insertion and retrieval of data from the Map you effectively know which hashCode() implementation is better.

    public class TestHashMap extends HashMap {
    
       public TestHashMap(int size) {
          super(size);
       }
    
       public TestHashMap() {
          super();
       }
    
       public int countCollidingEntries() {
          def fs = this.getClass().getSuperclass().getDeclaredFields();
          def table;
          def count =0 ;
          for ( java.lang.reflect.Field field: fs ) {
             if (field.getName() == "table") {
                field.setAccessible(true);
                table = field.get(super);
                break;
             }
          }
          for(Object e: table) {
             if (e != null) {
                while (e.next != null) {
                   count++
                   e = e.next;
                }
             }
          }
          return count;
       }
    }
    

提交回复
热议问题