关于Java中hashCode方法的实现源码

Posted alittlecomputer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Java中hashCode方法的实现源码相关的知识,希望对你有一定的参考价值。

首先来看一下String中hashCode方法的实现源码。

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;

       for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}

在String中有一个私有实例字段hash表示该串的哈希值,在第一次调用hashCode方法时,字符串的哈希值被计算并且赋值给hash字段。之后再调用hashCode方法便可以直接取hash字段返回。

 

String类中的hashCode计算方法还是比较简单的,就是一31为权,每一位字符的ASCII只进行计算,用自然溢出来等效取模。

哈希计算公式可以记为s[0]*31^(n-1)+s[1]*31^(n-2)+...+s[n-1]。

关于为什么取31为权,可以参考StackOverflow上的这个问题

主要原因是因为31是一个奇素数,所以31*i=32*i-i=(i<<5)-i,这种位移与剪发结合的计算相比一般的运算块很多。

字符串哈希可以做很多事情,通常是类似于字符串判等,判回文之类的。

但是仅仅依赖于哈希值来判断其实是不严谨的,除非能够保证不会有哈希值冲突。通常这一点很难做到。

就拿jdk中String类的哈希方法来举例,字符串“gdejicbegh”与字符串"hgebcijedg"具有相同的hashCode()返回值-801038016,并且他们具有reverse的关系。这个例子说明了用jdk中默认的hashCode方法判断字符串相等或者字符串回文都存在反例。

以上是关于关于Java中hashCode方法的实现源码的主要内容,如果未能解决你的问题,请参考以下文章

关于Java中的hashCode和equals方法

在java中,关于equals(),和hashCode()的重写问题。

Java实战源码解析为什么覆盖equals方法时总要覆盖hashCode方法

Java实战源码解析为什么覆盖equals方法时总要覆盖hashCode方法

Java中HashMap的实现原理

[ 转载 ] Java基础10--关于Object类下所有方法的简单解析