String的hashCode方法实现

来源:互联网 发布:php有没有开源erp系统 编辑:程序博客网 时间:2024/03/29 19:22
 /**     * Returns a hash code for this string. The hash code for a     * <code>String</code> object is computed as     * <blockquote><pre>     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]     * </pre></blockquote>     * using <code>int</code> arithmetic, where <code>s[i]</code> is the     * <i>i</i>th character of the string, <code>n</code> is the length of     * the string, and <code>^</code> indicates exponentiation.     * (The hash value of the empty string is zero.)     *     * @return  a hash code value for this object.     */    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;    }

计算公式是s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

31=2^5-1

31*h=h<<5-h

这样可以用移位和减法代替乘法,编译器会对乘法进行优化成移位和减法操作

下面是参考http://blog.csdn.net/steveguoshao/article/details/12576849的总结

 那么为什么选用31作为基数呢?先要明白为什么需要HashCode.每个对象根据值计算HashCode,这个code大小虽然不奢求必须唯一(因为这样通常计算会非常慢),但是要尽可能的不要重复,因此基数要尽量的大。另外,31*N可以被编译器优化为
左移5位后减1,有较高的性能。其实选用31还是有争议,反对者(参考http://stackoverflow.com/questions/299304/why-does-javas-hashcode-in-string-use-31-as-a-multiplier)
认为这个东西还是会导致较多的重复,应该用更大的数字。所以,或许将来Java的实现中会有所变化。下面这篇文章介绍了两个结论:
1.基数要用质数
质数的特性(只有1和自己是因子)能够使得它和其他数相乘后得到的结果比其他方式更容易产成唯一性,也就是hash code值的冲突概率最小。
2.选择31是观测分布结果后的一个选择,不清楚原因,但的确有利。

http://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/



0 0
原创粉丝点击