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

内部HashMap工作:如何在java中实现hashCode

滑令
2023-03-14

我正在努力为下面给出的学生类编写合适的hashCode函数。

1)我认为hashCode应该足够好,这样两个不同对象的hashCode就不会相互冲突。

观察:对于这个实现,当我调试并检查“HashMap的内部表对象”类时,我发现HashMap中的每个条目都分配了不同的bucket位置。

问题:在每个索引处有一个桶(列表/树)的目的是什么。

实施:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + id;
    return result;
}

2)如果我允许hashCode冲突:

观察:对于这个实现,当我调试和检查时,发现“hashMap内部表的大小”不断增加,并且只使用hashCode范围内的存储桶。其余所有存储桶索引显示为空。

问:如果超出hashCode范围的存储桶始终为空,那么增加内部表大小的目的是什么。

实施:

@Override
public int hashCode() {
    return id%20;
}

需要帮助以正确实施hashCode,以便修复上述问题。感谢您的提前帮助。

============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

public class HashMapTest {

public static void main(String a[]) {
    HashMap<Student, Integer> set = new HashMap<Student, Integer>();

    for (int i = 0; i < 5000; i++) {
        set.put(new Student(i), i);
    }

    set.put(new Student(5001), 5001);
    System.out.println(set.size());
}
}

class Student {
private int id;

public Student(int id) {
    this.id = id;
}

// Add here hashCode() provided in comments.


@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Student other = (Student) obj;
    if (id != other.id)
        return false;
    return true;
}

}

共有1个答案

匡晟
2023-03-14

在每个索引处有一个桶(列表/树)的目的是什么。

HashMap不要求哈希代码是唯一的,因为这通常无法实现(例如,有2 ^ 32个哈希码,但无限多的字符串,因此不可能为每个字符串使用不同的哈希代码)。相反,它只要求碰撞是罕见的。

因此,HashMap的实现使得即使存在冲突,它仍然可以正常工作(尽管在这种情况下它的工作速度可能会更慢)。这就是为什么HashMap使用可以在必要时存储多个元素的存储桶。

如果超出hashCode范围的桶总是空的,那么增加内部表大小的目的是什么?

HashMap调整表的大小,因为这样做会分割桶。通常,拆分一个桶会导致一些元素进入一个桶,另一些元素进入另一个桶中,从而提高性能。它没有意识到您的hashCode如此糟糕,以至于所有元素都将保留在同一个bucket中,因此继续尝试:-)

需要帮助才能正确实现哈希码,以便可以修复上述问题。

我会使用

@Override
public int hashCode() {
    return id;
}

如果id是唯一的(它的名字似乎暗示了这一点),这是一个完美的哈希函数,它甚至可以快速计算:-)

(请注意,hashCode可能大于表大小;HashMap将通过必要时截断它来解决这个问题)

 类似资料:
  • 本文向大家介绍Java中HashMap的内部工作,包括了Java中HashMap的内部工作的使用技巧和注意事项,需要的朋友参考一下 函数“ hashCode”用于获取Java中对象的哈希码。这是超类Object的对象。它以整数形式返回对象引用的内存。这是一个本机函数,这意味着Java中没有直接方法可用于获取对象的引用。 为了使HashMap的性能更好,请正确使用。基本上,此函数用于计算存储区和索引

  • 我对Java中和的内部实现有点困惑。 这是我的理解,所以如果我错了,请纠正我: < code>HashSet或< code>HashMap都不允许重复的元素。 < code>HashSet由< code>HashMap支持,所以在< code>HashSet中,当我们调用< code >时。add(element),我们在元素上调用< code>hashCode()方法,并在内部对内部< code

  • 问题内容: 我正在研究Java 的实现,只停留在一点。 该函数如何计算? 谢谢 问题答案: 它不是在计算 哈希 ,而是在计算 存储桶 。 表达确实逐位上使用,这是像一个位掩码,以便仅返回的低位比特,从而使得对于一个超高速变体。

  • 本文向大家介绍java HashMap内部实现原理详解,包括了java HashMap内部实现原理详解的使用技巧和注意事项,需要的朋友参考一下 详解HashMap内部实现原理 内部数据结构 从上面的数据结构定义可以看出,HashMap存元素的是一组键值对的链表,以什么形式存储呢 可以看出,是以数组形式储存,好的,现在我们知道,HashMap是以数组形式存储,每个数组里面是一个键值对,这个键值对还可

  • 问题内容: “类(及其子类)的每个实例都具有一个锁,该锁在方法进入时获得,并在退出时自动释放” 这是否意味着我们创建的任何对象实例默认情况下内部都具有“锁”(实现为字段)? 我对这个“锁”概念感到困惑,我想知道它实际上在内部做什么。 有人可以将我引导到一些我可以找到更多信息的地方吗? 问题答案: 与往常一样,JLS提供了答案(17.1): 这些方法中最基本的是同步,它是使用监视器实现的。Java中

  • 问题内容: 我正在阅读有关Java中并发性的Oracle官方文档,但我想知道返回的返回值之间可能有什么区别? 并使用例如 。我假设我用一个。我知道,一般而言,同步集合对于我来说只是一个装饰器,因此很明显a 的内部结构有所不同。您是否有关于这些实施细节的信息? 编辑:我意识到源代码是公开可用的: ConcurrentHashMap.java 问题答案: 我会阅读ConcurrentHashMap的源