为什么要向hashCode()添加一个常量? [英] Why would one add a constant to hashCode()?

查看:75
本文介绍了为什么要向hashCode()添加一个常量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Java的新手,最近我了解了 hashCode().在关于Java hashCode()的维基百科文章上,有以下 hashCode()方法:

I'm new to Java, and I've recently learned about hashCode(). On the wikipedia article about Java hashCode(), there is the following example of a hashCode() method:

public class Employee {
    int        employeeId;
    String     name;
    Department dept;

    // other methods would be in here

    @Override
    public int hashCode() {
        int hash = 1;
        hash = hash * 17 + employeeId;
        hash = hash * 31 + name.hashCode();
        hash = hash * 13 + (dept == null ? 0 : dept.hashCode());
        return hash;
    }
}

我知道乘以31和13会减少发生碰撞的机会,但是我不明白为什么 hash 初始化为1而不是 employeeId .最后,这只是在 hashCode()上加上17 * 31 * 13的效果,这不会改变两个hashCode()值是否相等.

I understand that multiplying by 31 and 13 decreases the chance of collision, but I don't see why hash is initialized to 1 rather than to employeeId. In the end this simply has the effect of adding 17*31*13 to the hashCode(), which is not going to change whether two hashCode() values are equal or not.

Bloch的"Effective Java(第二版)"在第9项(第47和48页)中有一个非常相似的示例,但是他对这个可加常数的解释对我来说还是很神秘的.

Bloch's "Effective Java (Second Edition)" has a very similar example in Item 9 (pages 47 and 48), but his explanation of this additive constant is quite mysterious to me.

该问题被标记为问题

This question was marked as a duplicate of the question Why does Java's hashCode() in String use 31 as a multiplier? That question is not the same: it is asking whether there is any reason to prefer the number 31 to any other number in the formula for the hashCode() of a String. My question is why it is the case that in many examples of hashCode() which I have found online there is a single constant added to the hashCode() of all objects.

实际上,这里的 String hashCode()示例是相关的,因为在该示例中没有添加常量.如果在我上面给出的示例中添加17 * 31 * 13起作用,为什么在计算 String hashCode()时不添加这样的常量?

In fact, the example of hashCode() of a String is relevant here, because in that example there is no constant added. If adding 17*31*13 has any effect in the example I gave above, why not add such a constant when computing hashCode() of a String?

推荐答案

以非零值开头在哈希码溢出或%非2的幂的情况下在概念上有帮助,这导致更多的位是不同的比较值,与之相比,溢出那些没有.

Starting with non zero value helps notionally when the hashCode overflows or is % by a non power of two which results in more bits being different comparing values which overflow compared to those which don't.

小常量不如大常量有效,但可以使用更少的字节并更快.例如.* 31更快,但可能不如* 109.

Small constants are not as effective as larger ones but can use less bytes and be faster. E.g. * 31 is faster but might not be as effective as * 109.

其区别取决于您的用例.

The difference it make depends on your use case.

注意:使用数字选择存储区后,即使确保您具有唯一的hashCode也不能确保没有冲突.

Note: even ensuring you have unique hashCodes doesn't ensure you have no collisions after the number has been used to select a bucket.

这篇关于为什么要向hashCode()添加一个常量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆