1. 把某个非零常数值,比如说17,保存在一个叫result的int类型的变量中。

2.对于对象中每一个关键域f(值equals方法中考虑的每一个域),完成以下步骤:

a.为该域计算int类型的散列吗c:

i. 如果该域是boolean类型,则计算

[java] view plain copy
f?0:1

ii. 如果该域是byte、char、short或者int类型,则计算
[java] view plain copy
(int)f

iii.如果该域是long类型,则计算
[java] view plain copy
(int)(f ^ (f >>> 32))

iv. 如果该域是double类型,则计算
[java] view plain copy
Double.doubleToLongBits(f)

得到一个long类型的值,然后按照2.a.iii,对该long型值计算散列值。

vi. 如果该域是一个对象引用,并且该类的equals方法通过递归调用equals的方式来比较这个域,则同样对这个域递归调用hashCode,如果要求一个更为复杂的比较,则为这个域计算一个“规范表示(canonical representation)”,然后针对这个范式调用hashCode。如果这个域为null,则返回0(或者是某个常数,但习惯上使用0)。

vii. 如果该域是一个数组,则把每一个元素当做单独的域处理。也就是说,递归地应用上诉规则,对每一个重要的元素计算散列值,然后根据2.b的方法把这些散列值组合起来。

b.按照下面的公式,把步骤a得到的散列值组合到result中:

[java] view plain copy
result = 37 * result + c;

3.返回result
4.写完了hashCode后,问自己相等的实例具有相同的hashCode么?假如不是,找出原因并修正。

在散列码的计算过程中,把冗余域排除在计算之外是可以接受的。换句话说,如果一个域的值可以根据其他域值计算出来,则把这样的域排除在外是可以接受的。

举例,假如一个类PhoneNumber有三个关键域:areaCode,exchange,extension,都是short类型,则hashCode的计算过程为:

[java] view plain copy
@Override
public int hashCode(){
int result = 17;
result = result * 37 + areaCode;
result = result * 37 + exchange;
result = result * 37 + extension;
return result;
}
如果一个类是可变的,并且计算散列码的代价也比较大,那么你应该考虑把散列码缓存到对象的内部,而不是每次请求的时候都计算散列值。如果你觉得这种类型的大都数值会被用作散列键,那么你应该在实例被创建的时候计算散列值,否则,你可以选择“延迟初始化”散列码,一直到hashCode第一次调用才开始计算。
假如PhoneNumber这样处理,那么代码为:

[java] view plain copy
//延迟初始化
private volatile int hashCode = 0;

@Override
public int hashCode(){
if(hashCode == 0){
int result = 17;
result = result * 37 + areaCode;
result = result * 37 + exchange;
result = result * 37 + extension;
hashCode = result;
}
return hashCode;
}

计算hashCode的常见方法的更多相关文章

  1. 用HashSet的add方法谈hashcode和equals方法重写

    本文主要通过用HashSet的add方法讲一下hashCode和equals方法重写.错误的地方望指正. 1.了解HashSet的add方法 了解一个方法的好办法是看源码,所以先看源码 private ...

  2. java——HashCode和equal方法

    equals()反映的是对象或变量具体的值,即两个对象里面包含的值--可能是对象的引用,也可能是值类型的值. 而hashCode()是对象或变量通过哈希算法计算出的哈希值. 之所以有hashCode方 ...

  3. 为什么要重写hashcode和equals方法?初级程序员在面试中很少能说清楚。

    我在面试 Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分, ...

  4. 【转】 如何重写hashCode()和equals()方法

    转自:http://blog.csdn.net/neosmith/article/details/17068365 hashCode()和equals()方法可以说是Java完全面向对象的一大特色.它 ...

  5. 关于hashMap中 计算hashCode的逻辑推理(二)

    hashMap中,为了使元素在数组中尽量均匀的分布,所以使用取模的算法来决定元素的位置.如下: //方法一: static final int hash(Object key){//jdk1.8 in ...

  6. hashcode和equals方法的区别和联系

    说到 hashcode就要和Java中的集合,HashSet,HashMap 关系最为密切. 首先附录两张Java的集合结构图: 图二:(上图的简化版) 从Set集合的特点说起 & Set是如 ...

  7. 如何重写hashCode()和equals()方法

    hashCode()和equals()方法可以说是Java完全面向对象的一大特色.它为我们的编程提供便利的同时也带来了很多危险.这篇文章我们就讨论一下如何正解理解和使用这2个方法. 如何重写equal ...

  8. 使用对象作为hashMap的键,需要覆盖hashcode和equals方法

    1:HashMap可以存放键值对,如果要以对象(自己创建的类等)作为键,实际上是以对象的散列值(以hashCode方法计算得到)作为键.hashCode计算的hash值默认是对象的地址值. 这样就会忽 ...

  9. (转)为什么要重写 hashcode 和 equals 方法?

    作者丨hsm_computer cnblogs.com/JavaArchitect/p/10474448.html 我在面试Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候 ...

随机推荐

  1. OutputCache 如何使用本地缓存 【转】

    注意!ASP.NET MVC 3 的一个 OutputCache 问题   在用 ASP.NET MVC 3 重写博客园网站首页时,特地留意了一下这个缓存问题,通过这篇博文分享一下. 在 ASP.NE ...

  2. BZOJ 1433 二分图上的博弈

    首先对网格染色,发现是而二分图. 那么即在二分图上选一个起点走过的点无法再走,最后无路可走就输了. 如果起点必在最大匹配中,先手必赢. 如果起点不一定在最大匹配中(包括不可能在),后手必赢.网上有解释 ...

  3. php建立MySQL数据表

    <?php $connect = mysql_connect("127.0.0.1","root",""); mysql_select ...

  4. uva 10622

    http://vjudge.net/contest/140673#problem/H 求某个数字(最大到10^9,可为负值)写成完全p次方数的指数p是多少 分析: 先进行唯一分解,之后p整除各个素因子 ...

  5. C#常见控件命名规则举例

    控件       缩写  举例 Adrotator adrt adrtTopAd BulletedList blst blstCity Button btn btnSubmit Calendar ca ...

  6. repeater没有数据显示暂无数据,无记录

    方法就是在FooterTemplate加个Label并根据repeater.Items.Count判断是否有记录.关键代码如下: <FooterTemplate> <asp:Labe ...

  7. JSON.parse()的正确用法

    昨天晚上在项目中使用JSON.parse()来将字符串格式的数据转换成json,结果悲剧了,总感觉方法没有用错,可是就是报错!想了好久,最后发现原来是json字符串格式不标准! 如:var a = “ ...

  8. SocketTcpClient

    public class SocketTcpClient { public static string ErrorMsg = string.Empty; private static Socket _ ...

  9. 复制到剪贴板的JS实现--ZeroClipboard (兼解决IE下兼容问题)

    复制到剪贴板的JS实现--ZeroClipboard (兼解决IE下兼容问题) 相信绝大多数人都遇到过这样的功能实现,“复制”或者“复制到剪贴板”这样的功能.但是由于各大浏览器的实现方案不一样,导致几 ...

  10. asp 实现域名转向

    <% host=lcase(request.servervariables("HTTP_HOST")) select CASE host CASE "aa.cn&q ...