zoukankan      html  css  js  c++  java
  • Hashcode方法代码解析

    几周前学习Java时了解到hashcode方法,它会生成一行唯一的hash值来判定两个目标是否相等,我对这个生成的hash有点疑惑,它是根据什么做的hash呢???难道是根据时间?代码量?内存地址?

    这是Java中的String类型hash

    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是使用 String 的 char 数组的数字每次乘以 31 再叠加最后返回,因此,每个不同的字符串,返回的 hashCode 肯定不一样。

    我又有疑惑了那么为什么使用 31这个魔数 呢?

    在名著 《Effective Java》第 42 页就有对 hashCode 为什么采用 31 做了说明:
    之所以使用 31, 是因为他是一个奇素数。如果乘数是偶数,并且乘法溢出的话,信息就会丢失,因为与2相乘等价于移位运算(低位补0)。使用素数的好处并不很明显,但是习惯上使用素数来计算散列结果。 31 有个很好的性能,即用移位和减法来代替乘法,可以得到更好的性能: 31 * i == (i << 5) - i, 现代的 VM 可以自动完成这种优化。这个公式可以很简单的推导出来。
    在栈溢出论坛(Stackoverflow)里面有很多小伙伴的讨论,大家可以去看一看。。。
    点我 Stackoverflow
    好吧,使用 31 最主要的还是为了性能。没有最合适,只有更合适,关于散列计算问题,我在知乎上看到有人做过统计选取,当选取的数大于31时,hash码的分布会非常的分散,很多”数串“没有用到。而选取小于31的数时,hash出来的hash值会存在很高的重复度,而且散列分布很集中。至于31怎么来的,或许是James Gosling老爷子试出来的吧!
    如果再往深究,就是数学方面的范畴了。
    还有很多人会疑惑就是--------怎么都找不到重复的hashCode的例子。下面来一个

    String a=“Aa”;String b=“BB”;

    int c=a.hashCode(); 2122 int d=b.hashCode();2122 所得hashCode就是重复的。

  • 相关阅读:
    站立会议08
    站立会议07
    站立会议06
    站立会议05
    SOA架构设计的案例分析
    java实现根据高德地图API接口进行地址位置解析,将地址转化为经纬度
    java实现根据起点终点和日期查询去哪儿网的火车车次和火车站点信息
    Cocos2d切换场景出现的问题-error C2653: “***”不是类或命名空间名称
    云时代架构之点融支付系统架构的演进
    云时代架构之百度万人协同规模下的代码管理架构演进
  • 原文地址:https://www.cnblogs.com/AmosAlbert/p/12832277.html
Copyright © 2011-2022 走看看