当前位置: 首页 > 知识库问答 >
问题:

HashMap为什么以及如何拥有自己的hashCode()内部实现叫做hash()?

许华清
2023-03-14

根据这篇博客文章,HashMap在已经检索到的hashCode上重新调用它自己的< code>hashCode()(称为< code>hash())实现。

如果key不为null,那么它将在key对象上调用哈希函数,参见上面方法中的第4行,即key.hashCode(),所以key.hashCode()返回hashValue后,第4行看起来像

int hash=hash(hashValue)

现在,它将返回的hashValue应用到自己的散列函数中。

我们可能想知道为什么我们再次使用哈希值(hashValue)计算哈希值。答案是,它可以抵御质量差的哈希

HashMap可以准确地重新分配哈希码吗?HashMap可以存储对象,但它无权访问为hashCode分配对象的逻辑。例如,hash()不可能集成以下hashCode()实现背后的逻辑:

public class Employee {
protected long employeeId;
protected String firstName;
protected String lastName;

public int hashCode(){
    return (int) employeeId;
}

}

共有1个答案

印成天
2023-03-14

hash() 从实际的哈希代码派生“改进的”哈希代码,因此相等的输入将始终是相等的输出(来自jdk1.8.0_51):

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

至于为什么散列代码需要改进,请阅读该方法的javadoc:

计算密钥.哈希码()并将哈希的较高位传播(XOR)到较低位。由于该表使用二次幂掩码,因此仅在当前掩码上方的位上变化的哈希集将始终发生冲突。(已知示例包括一组 Float 键,这些键在小表中保存连续的整数。因此,我们应用了一个转换,将更高位的影响向下传播。在速度、效用和位传播质量之间需要权衡。因为许多常见的哈希集已经合理地分布了(所以不会从传播中受益),并且因为我们使用树来处理箱中的大量冲突,所以我们只是以最便宜的方式XOR一些移动位,以减少系统损失,以及合并最高位的影响,否则这些最高位永远不会用于索引计算,因为表边界。

 类似资料:
  • 我正在努力为下面给出的学生类编写合适的hashCode函数。 1)我认为hashCode应该足够好,这样两个不同对象的hashCode就不会相互冲突。 观察:对于这个实现,当我调试并检查“HashMap的内部表对象”类时,我发现HashMap中的每个条目都分配了不同的bucket位置。 问题:在每个索引处有一个桶(列表/树)的目的是什么。 实施: 2)如果我允许hashCode冲突: 观察:对于这

  • 房间类别 长话短说,这一点是为了添加房间,并能够导航它们,捡起物品,然后放下它们。在我尝试运行程序时,我注意到我不能有多个北/南/东/西键。我怎样才能避开这件事,这样我才能把它做好?

  • 本文向大家介绍ArrayList和HashMap如何自己实现实例详解,包括了ArrayList和HashMap如何自己实现实例详解的使用技巧和注意事项,需要的朋友参考一下  ArrayList和HashMap ArrayList的存储就是一个数组, HashMap的存储是一个数组加一个链表, 以下实现的MyArrayList及MyHashMap,在实际的工作中都是用不上的,最有可能用得到的地方就是

  • 问题内容: 我读到HashMap具有以下实现: 因此,它具有一个Entry对象数组。 问题: 我想知道在相同hashCode但不同对象的情况下,此数组的索引如何存储多个Entry对象。 这与实施有何不同?它的map的双链列表实现,但它是否像上面那样维护数组,以及如何存储指向下一个和上一个元素的指针? 问题答案: 因此,它具有对象数组。 不完全是。它具有一系列对象 链 。一个对象有一个字段,允许对象

  • 根据我所读到的, 要使用对象作为hashMap的键,它必须提供正确的重写和equals和hashCode方法的实现。HashMap get(Key k)方法调用Key对象上的hashCode方法,并将返回的hashValue应用到它自己的静态哈希函数中,以找到一个桶位置(备份数组),键和值以名为Entry(Map.Entry)的嵌套类的形式存储在这里。HashMap的内部哈希方法防御质量差的哈希函

  • 重写Compariable接口的compareTo()方法的最佳方法是什么?此外,当我们可以编写自己的compareTo()方法而无需实现时,为什么还要实现可比较的接口呢。以以下座椅类别为例: 尽管我们没有实现可比接口,但上述工作仍然有效,那么我们为什么要实现它呢?