【问题标题】:Hashmap with two key object having same value but different bucket index具有两个具有相同值但不同存储桶索引的键对象的 Hashmap
【发布时间】:2019-03-20 11:11:52
【问题描述】:

如果 Hashmap 有两个具有相同值的键,例如:

HashMap map=new HashMap();
map.put("a","abc");
map.put("a","xyz");   

所以这里放了两个带有“a”值的键,假设第一个 bucketindex=1 和 第二个bucketindex=9

所以我的问题是,两者的存储桶索引是否会在之后有所不同 应用散列算法,在此如何处理不插入 重复键,因为它已经存在并且 hashmap 不能重复 钥匙。 请提出您对此的看法。

【问题讨论】:

  • 所以请定义“bucketindex”
  • Bucket Index - “每个bucket都有一个唯一的编号——这就是bucket的标识。”

标签: java hashmap


【解决方案1】:

不会有“第二桶索引”之类的东西。

我建议您添加类似 System.out.println(map.toString()) 的内容,以查看第二个 put() 对您的地图所做的操作。

编辑:

put(key,value) 方法中,“桶索引”是作为 key 元素值的函数计算的,而不是 value 元素值的函数(因此“a”和“a”为桶)。这个函数应该是确定性的,所以给它提供相同的值(在你的例子中是“a”),相同的 hashCode() 将出现,随后,相同的桶索引。

【讨论】:

  • 如果我有 String key1="a" 和 String key2="a" 现在哈希码值可以不同,因为它是基于对象计算的,并且假设哈希给出不同的桶索引并且存在是否有可能获得不同的价值。
  • 这就是为什么类可以覆盖 hashCode() 的实现,并且必须有效地这样做才能使它们可用作 HashMap 中的键。 String 类有效地做到了这一点。不要那样做,各种疯狂的事情(统称为“不可预测的结果”)就会开始发生。
  • PS 此外,hashCode() 必须在某种意义上实现“与equals 一致”:如果x1.equals(x2) 返回true,则x1.hashCode() 和x2。 hashCode() 必须返回相同的值。另请注意,还有其他一些方法可以导致疯狂的事情发生,例如使 hashCode() 所基于的状态部分可变。
【解决方案2】:

在 Java 中,如果散列函数返回相同的散列,则两个对象的相等性由 equals() 方法确定。如果发现对象相等,则只需将旧对象替换为新对象。

相反,如果对象不相等,它们只是链接在一个链表(或平衡树)中,并且地图包含这两个对象,因为它们不同

所以,回到您的问题:“如果在应用散列算法后两者的存储桶索引不同” - 这对于相等的对象是不可能的。相等的对象必须具有相同的哈希码。

【讨论】:

  • hashcode 值是如何生成的,就像原生方法为任何对象生成 hashcode 值一样?
  • @RahulMahajan 没有生成,它使用 java.lang.Object 的默认 hashCode() 方法。如果你想实现你的哈希函数,你只需要重写 hashCode() 方法并提供你的哈希算法。
【解决方案3】:

为了让@Erwin 的回答更清楚,这里是来自JDK 的HashMap 的源代码

public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}

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

再深入挖掘你会发现桶索引是根据key的哈希码计算出来的。

为了简单明了,将具有不同值的重复键放入同一个HashMap 将只产生一个条目,第二个放入只是覆盖条目的值。

【讨论】:

    【解决方案4】:

    如果您的问题是如何创建一个可以为同一个键处理多个值的哈希映射,那么您需要的是一个 Map>,这样每次键相同时它都会向数组列表添加一个新值。

    【讨论】:

      猜你喜欢
      • 2016-11-23
      • 2014-08-18
      • 2013-10-16
      • 1970-01-01
      • 2018-05-22
      • 1970-01-01
      • 2018-01-13
      • 1970-01-01
      • 2015-11-22
      相关资源
      最近更新 更多