Java对象的hashCode的计算

当我们查看JDK源码或者一些有名的Java框架时,在一些hashcode的计算算法时都会出现31、29、17,那么为什么这样呢?这个数是不是可以任意的数字?

以下是一些框架,jdk源码中的hashcode的计算

//lucene8.11中的RAMFile类的hashcode计算
public class RAMFile{
    //other code
    public int hashCode() {
        int h = (int) (length ^ (length >>> 32));
        for (byte[] block : buffers) {
            h = 31 * h + Arrays.hashCode(block);
        }
        return h;
    }
}

//JDK中工具类的Arrays的计算hashcode
public class Arrays{
    public static int hashCode(byte a[]) {
        if (a == null)
            return 0;
    
        int result = 1;
        for (byte element : a)
            result = 31 * result + element;
    
        return result;
    }
}

Java中hashCode方法的设计经常涉及到将对象的某些字段值转换成整数,并且通常这些整数值会乘以一个质数(比如31),然后加上或减去其他字段的整数值。使用质数(特别是像31这样的小质数)的原因主要有以下几点:

  1. 减少冲突
    质数在模运算下具有较好的分布特性,可以减少哈希冲突。哈希冲突是指不同的输入产生了相同的哈希值。使用质数作为乘数可以增加哈希值的分布范围,从而减少冲突的可能性。
  2. 性能考虑
    31是一个比较小的质数,用31作为乘数在计算机运算中效率较高。具体来说,31 * i 相当于 (i << 5) - i,这是一个位移和减法的组合操作,在二进制层面是非常高效的。位移操作比乘法操作要快,而减法操作也相对较快。
  3. 避免整数溢出
    Java中的hashCode方法返回的是int类型,其取值范围是-231到231-1。使用较小的质数如31作为乘数可以减小在计算过程中整数溢出的风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风吹千里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值