【问题标题】:Regarding collision in Map关于地图中的碰撞
【发布时间】:2012-08-02 14:12:57
【问题描述】:

我正在浏览HashMap并阅读以下分析..

  1. HashMap 实例有两个影响其性能的参数:初始容量和负载因子。

  2. 容量是哈希表中的桶数,初始容量就是哈希表创建时的容量。

  3. 负载因子衡量哈希表在其容量自动增加之前允许达到的程度。

  4. 当哈希表中的条目数超过负载因子和当前容量的乘积时,哈希表被重新哈希(即内部数据结构被重建),使得哈希表大约有两倍桶的数量。

  5. 默认初始容量为16,默认负载系数为0.75。您可以在地图的构造函数中提供其他值。

现在假设我有一张地图..

HashMap map=new HashMap();//HashMap key random order.
         System.out.println("Amit".hashCode());
         map.put("Amit","Java");
         map.put("mAit","J2EE");
         map.put("Saral","J2rrrEE");

我希望发生碰撞,请告知碰撞将如何发生..!!

【问题讨论】:

  • 对不起,我不明白这个,“请告知碰撞是如何发生的” - 为什么你需要一定发生碰撞?
  • “我希望发生碰撞”。为什么?这正是你应该尝试避免

标签: java collections hashmap


【解决方案1】:

我相信确切的 hashmap 行为取决于实现。只要看看你的类库正在做散列并构造一个冲突。这很简单。

如果您希望在任意对象而不是字符串上发生碰撞,这要容易得多。只需使用始终为 returns 0 的自定义 hashCode() 创建一个类。

【讨论】:

    【解决方案2】:

    当 2 个 key 具有相同的 hash key 时会发生冲突。 我没有计算你的键散列键,但我不认为它们具有相同的散列键,因此如果它们没有相同的散列键,则不会发生冲突。 如果您将与键相同的字符串放在一起,则会发生冲突

    【讨论】:

      【解决方案3】:

      如果您希望发生真正的冲突,那么最好编写您自己的自定义哈希码。比如说,如果你想AmitmAit 发生冲突,你可以做一件事,只需使用字符的 ascii 值作为哈希码。你会因为不同的键而发生冲突。

      【讨论】:

      • 所以我将编写自己的重写 hashcode() 方法,并为所有人返回相同的 hashcode()..!!
      【解决方案4】:

      这里的冲突绝对是可能的,并且与哈希表实现无关。 HashMap 在内部工作,通过使用 Object.hashCode 将对象映射到存储桶,然后与 Object.equals 一起使用冲突解决机制(OpenJDK 实现使用分离链)。

      为了回答您的问题,String.hashCode 已明确定义为兼容性...

      返回此字符串的哈希码。 String 对象的哈希码计算为 s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

      使用int算术,其中s[i]是字符串的第i个字符,n是字符串的长度,^表示求幂。 (空字符串的哈希值为零。)

      或者,在代码中(来自OpenJDK

      public int hashCode() {
          int h = hash;
          if (h == 0 && count > 0) {
              int off = offset;
              char val[] = value;
              int len = count;
      
              for (int i = 0; i < len; i++) {
                  h = 31*h + val[off++];
              }
              hash = h;
          }
          return h;
      }
      

      与任何散列函数一样,冲突是可能的。根据Wikipedia article,它指出例如"FB""Ea" 会产生相同的值。

      如果你想要更多,在这里找到具有相同哈希值的冲突应该是一个微不足道的暴力问题。


      作为旁注,我想我会指出这与 C 编程语言第二版中的函数非常相似:

      #define HASHSIZE 100
      
      unsigned hash(char *s)
      {
          unsigned hashval;
      
           for(hashval = 0; *s != '\0'; s++)
               hashval = *s + 31 * hashval;
      
           return hashval % HASHSIZE;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多