文档章节

如何生成一个合适的hashcode方法

LCZ777
 LCZ777
发布于 2014/03/31 15:11
字数 856
阅读 27
收藏 0

Hashcode在基于key-value的集合如:HashMap、LinkedHashMap中扮演很重要的角色。此外在HashSet集合中也会运用到,使用合适的hashcode方法在检索操作时的时间复杂度最好的是 O(1).

一个差劲的hashcode算法不仅会降低基于哈希集合的性能,而且会导致异常结果。Java应用中有多种不同的方式来生成hashcode。

Effective Java

Josh Bloch在他的书籍《Effective Java》告诉我们重写hashcode方法的最佳实践方式。

一个好的hashcode方法通常最好是不相等的对象产生不相等的hash值,理想情况下,hashcode方法应该把集合中不相等的实例均匀分布到所有可能的hash值上面。

  1. 把某个非0的常数值,比如17,保存在一个名为result的int类型的变量中。
  2. 对于对象中的每个域,做如下操作:
    • 为该域计算int类型的哈希值c:
      • 如果该域是boolean类型,则计算(f?1:0)
      • 如果该域是byte、char、short或者int类型,则计算(int)f
      • 如果该域是long类型,则计算(int)(f^(f>>>32))
      • 如果该域是float类型,则计算Float.floatToIntBits(f)
      • 如果该域是double类型,则计算Double.doubleToLongBits(f),然后重复第三个步骤。
      • 如果该域是一个对象引用,并且该类的equals方法通过递归调用equals方法来比较这个域,同样为这个域递归的调用hashCode,如果这个域为null,则返回0。
      • 如果该域是数组,则要把每一个元素当作单独的域来处理,递归的运用上述规则,如果数组域中的每个元素都很重要,那么可以使用Arrays.hashCode方法。

把上面计算得到的hash值c合并到result中

1
result =31*result + c

String中的Hashcode方法

String的hashcode的算法就充分利用了字符串内部字符数组的所有字符。生成hash码的算法的在string类中看起来像如下所示,注意“s“是那个字符数组,n是字符串的长度。

1
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

Hashcode使用Eclipse IDE

现代IDE通过点击右键上下文菜单可以自动生成hashcode方法,通过Eclipse IDE 生成的hashcode像:

1
2
3
4
5
6
publicinthashCode() {
finalintprime =31;
intresult =1;
result = prime * result + a;
returnresult;
}

但是并不推荐如上代码使用在企业级代码中,最好使用第三方库如Apache commons来生成hashocde方法。

Apache commons HashcodeBuilder

我们可以用Apache Commons hashcode builder来生成代码,使用这样一个第三方库的优势是可以反复验证尝试代码。下面代码显示了如何使用Apache Commons hash code 为一个自定义类构建生成hash code 。

1
2
3
4
5
6
7
publicinthashCode(){
HashCodeBuilder builder =newHashCodeBuilder();
builder.append(mostSignificantMemberVariable);
........................
builder.append(leastSignificantMemberVariable);
returnbuilder.toHashCode();
}

如上面代码显示的,最重要的签名成员变量应该首先传递然后跟随的是没那么重要的成员变量。

Apache Commons库同样为自定义的类提供了构建生成equals的方法,使用equals构建器的代码看起来非常像上面的代码。事实上传递给成员变量从最重要的签名到最不重要的签名一样的规则,同样应用于equals构建器中。

本文转载自:

LCZ777
粉丝 53
博文 248
码字总数 65899
作品 0
杭州
程序员
私信 提问
Java中常见数据结构:List与Map

1:集合 2.关于集合选取原则 3:集合的常见方法及遍历方式 --Set

不负好时光
07/10
68
0
java中HashMap的用法

重点介绍HashMap。首先介绍一下什么是Map。在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value。在下文中...

常翔
2012/11/23
7.8K
0
hashcode()方法

 浅谈Java中的hashcode方法   哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率。在Java的Object类中有一个方法:   为何Object类需要这样一个方...

HenrySun
2015/09/21
95
0
Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法

Tips 《Effective Java, Third Edition》一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时间,但随着Java 6,7,8...

M104
2018/01/02
0
0
Java 中正确使用 hashCode 和 equals 方法

在这篇文章中,我将告诉大家我对hashCode和equals方法的理解。我将讨论他们的默认实现,以及如何正确的重写他们。我也将使用Apache Commons提供的工具包做一个实现。 目录: hashCode()和equ...

王振威
2012/10/21
66.8K
43

没有更多内容

加载失败,请刷新页面

加载更多

Taro 兼容 h5 踩坑指南

最近一周在做 Taro 适配 h5 端,过程中改改补补,好不酸爽。 本文记录📝遇到的问题,希望为有相同需求的哥们👬节约点时间。 Taro 版本:1.3.9。 解决跨域问题 h5 发请求会报跨域问题,需...

dkvirus
今天
4
0
Spring boot 静态资源访问

0. 两个配置 spring.mvc.static-path-patternspring.resources.static-locations 1. application中需要先行的两个配置项 1.1 spring.mvc.static-path-pattern 这个配置项是告诉springboo......

moon888
今天
3
0
hash slot(虚拟桶)

在分布式集群中,如何保证相同请求落到相同的机器上,并且后面的集群机器可以尽可能的均分请求,并且当扩容或down机的情况下能对原有集群影响最小。 round robin算法:是把数据mod后直接映射...

李朝强
今天
4
0
Kafka 原理和实战

本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/bV8AhqAjQp4a_iXRfobkCQ 作者简介:郑志彬,毕业于华南理工大学计算机科学与技术(双语班)。先后从事过电子商务、开放平...

vivo互联网技术
今天
19
0
java数据类型

基本类型: 整型:Byte,short,int,long 浮点型:float,double 字符型:char 布尔型:boolean 引用类型: 类类型: 接口类型: 数组类型: Byte 1字节 八位 -128 -------- 127 short 2字节...

audience_1
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部