前提:

  偶然的机会看到了大神的一篇博客,介绍的是hashCode()方法里为什么要用31这个数字作为生成hashCode的乘数。hashCode我在比较自定义类时曾经用到过 - 由于java默认比较的是类的地址值,每个对象一定是不同的,所以重写了hashCode()和equals()方法
,这样就会先根据类里的属性生成hashCode,如果生成的hashCode值相同,则在使用equals()比较属性的值。两者都相同则认为这两个对象相等。当是就对hashCode的生成很好奇,自己看了下源码也是懵懵懂懂。这下终于可以搞清楚了,开森,感谢大佬!

  hashCode()方法的源码:

原因一:更少的乘积结果冲突

  31是质子数中一个“不大不小”的存在,如果你使用的是一个如2的较小质数,那么得出的乘积会在一个很小的范围,很容易造成哈希值的冲突。而如果选择一个100以上的质数,得出的哈希值会超出int的最大范围,这两种都不合适。而如果对超过 50,000 个英文单词(由两个不同版本的 Unix 字典合并而成)进行 hash code 运算,并使用常数 31, 33, 37, 39 和 41 作为乘子,每个常数算出的哈希值冲突数都小于7个(国外大神做的测试),那么这几个数就被作为生成hashCode值得备选乘数了。

原因二:31可以被JVM优化

  JVM里最有效的计算方式就是进行位运算了:

* 左移 << : 左边的最高位丢弃,右边补全0(把 << 左边的数据*2的移动次幂)。
* 右移 >> : 把>>左边的数据/2的移动次幂。
* 无符号右移 >>> : 无论最高位是0还是1,左边补齐0。
  

所以 : 31 * i = (i << 5) - i(左边  31*2=62,右边   2*2^5-2=62) - 两边相等,JVM就可以高效的进行计算啦。。。

  ps:以前家里人老说学号数理化,走遍全天下。貌似很有道理^_^

hashCode方法里为什么选择数字31作为生成hashCode值的乘数的更多相关文章

  1. String hashCode 方法为什么选择数字31作为乘子

    1. 背景 某天,我在写代码的时候,无意中点开了 String hashCode 方法.然后大致看了一下 hashCode 的实现,发现并不是很复杂.但是我从源码中发现了一个奇怪的数字,也就是本文的主 ...

  2. 科普:String hashCode 方法为什么选择数字31作为乘子

    1. 背景 某天,我在写代码的时候,无意中点开了 String hashCode 方法.然后大致看了一下 hashCode 的实现,发现并不是很复杂.但是我从源码中发现了一个奇怪的数字,也就是本文的主 ...

  3. 【转】String hashCode 方法为什么选择数字31作为乘子

    某天,我在写代码的时候,无意中点开了 String hashCode 方法.然后大致看了一下 hashCode 的实现,发现并不是很复杂.但是我从源码中发现了一个奇怪的数字,也就是本文的主角31.这个 ...

  4. JDK1.8源码学习-String-hashCode方法为什么选择数字31作为乘子

    1. 背景 某天,我在写代码的时候,无意中点开了 String hashCode 方法.然后大致看了一下 hashCode 的实现,发现并不是很复杂.但是我从源码中发现了一个奇怪的数字,也就是本文的主 ...

  5. 科普:为什么 String hashCode 方法选择数字31作为乘子

    作者:coolblog 此文章转载自:https://segmentfault.com/a/1190000010799123 1. 背景 某天,我在写代码的时候,无意中点开了 String hashC ...

  6. Java中的equals和hashCode方法

    本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要 ...

  7. equals(),hashcode()方法详解

    Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这两个方法,今天就来介绍一些这两个方法的作用. equals ...

  8. java集合(3)- Java中的equals和hashCode方法详解

    参考:http://blog.csdn.net/jiangwei0910410003/article/details/22739953 Java中的equals方法和hashCode方法是Object ...

  9. Java中的equals和hashCode方法详解

    Java中的equals和hashCode方法详解  转自 https://www.cnblogs.com/crazylqy/category/655181.html 参考:http://blog.c ...

随机推荐

  1. linux4 分区

    分区 对硬盘分区:安装操作系统的时候有一个分区过程,新增加硬盘也会涉及到分区,如何给操作系统新增一台硬件设备. 启动操作系统. Home是当前账号的根目录,Computer是/系统根目录. ~是当前账 ...

  2. Spring AOP-xml配置

    在spring AOP(一)中介绍了AOP的基本概念和几个术语,现在学习一下在XML中如何配置AOP. 在XML中AOP的配置元素有以下几种: AOP配置元素 描述 <aop:config> ...

  3. [RK3288][Android6.0] 调试笔记 --- 替换系统签名【转】

    本文转载自:http://blog.csdn.net/kris_fei/article/details/55100299 Platform: RK3288OS: Android 6.0Kernel: ...

  4. 人生苦短之Python函数的健壮性

    如何评论一个开发代码写的好?清晰简洁明了?No,No,一个处女座就可以写出来了,整齐地代码,详细的注释不是代码好的标准,应该说不是最重要的标准.代码写的是否健壮才是检验的重要标准. 代码的健壮性: 当 ...

  5. linux命令行快捷键记录

    摘自: http://www.cnblogs.com/webzhangnan/p/3221410.html [移动光标] Ctrl+A 标移到行首.它在多数文本编辑器和 Mozilla 的 URL 字 ...

  6. html5--4-2 video元素的属性

    html5--4-2 video元素的属性 学习要点 掌握video元素的基本用法 直到现在,在网页中的大多数视频是通过插件(比如 Flash)来显示的.然而,并非所有浏览器都拥有同样的插件.HTML ...

  7. yii表单的各种验证

    /验证规则详细配置 public function rules() { // NOTE: you should only define rules for those attributes that ...

  8. BigDecimal 实际测试结果

    package com.zzzy; import java.math.BigDecimal; public class Test { public static void main(String[] ...

  9. cuda 版本查阅

    查看cuda版本 cat  /usr/local/cuda/version.txt nvcc -V

  10. 杂项:SVN 常用方法

    ylbtech-杂项:SVN 1.返回顶部 1. bin obj *.suo*.user *.csproj.user *.o *.lo *.la *.al .libs *.so *.so.[0-9]* ...