Item 9 覆盖equals时总要覆盖hashCode
为什么覆盖equals时,总要覆盖hashCode?
import java.util.HashMap;
import java.util.Map; public final class PhoneNumber {
private final short areaCode ;
private final short prefix ;
private final short lineNumber ; public PhoneNumber( int areaCode, int prefix, int lineNumber) {
rangeCheck(areaCode, 999, "area code");
rangeCheck(prefix, 999, "prefix" );
rangeCheck(lineNumber, 9999, "line number");
this. areaCode = ( short) areaCode;
this. prefix = ( short) prefix;
this. lineNumber = (short ) lineNumber;
} private static void rangeCheck(int arg, int max, String name) {
if (arg < 0 || arg > max)
throw new IllegalArgumentException(name + ": " + arg);
} @Override
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof PhoneNumber))
return false;
PhoneNumber pn = (PhoneNumber) o;
return pn. lineNumber == lineNumber && pn.prefix == prefix && pn. areaCode == areaCode;
} // Broken - no hashCode method! // A decent hashCode method - Page 48
// @Override public int hashCode() {
// int result = 17;
// result = 31 * result + areaCode;
// result = 31 * result + prefix;
// result = 31 * result + lineNumber;
// return result;
// } // Lazily initialized, cached hashCode - Page 49
// private volatile int hashCode; // (See Item 71)
//
// @Override public int hashCode() {
// int result = hashCode;
// if (result == 0) {
// result = 17;
// result = 31 * result + areaCode;
// result = 31 * result + prefix;
// result = 31 * result + lineNumber;
// hashCode = result;
// }
// return result;
// } public static void main(String[] args) {
Map<PhoneNumber, String> m = new HashMap<PhoneNumber, String>();
m.put (new PhoneNumber(707, 867, 5309), "Jenny");
System.out.println(m.get( new PhoneNumber(707, 867, 5309)));
}
}
public final class PhoneNumber {
private final short areaCode ;
private final short prefix ;
private final short lineNumber ;
public PhoneNumber( int areaCode, int prefix, int lineNumber) {
rangeCheck(areaCode, 999, "area code");
rangeCheck(prefix, 999, "prefix" );
rangeCheck(lineNumber, 9999, "line number");
this. areaCode = ( short) areaCode;
this. prefix = ( short) prefix;
this. lineNumber = (short ) lineNumber;
}
private static void rangeCheck(int arg, int max, String name) {
if (arg < 0 || arg > max)
throw new IllegalArgumentException(name + ": " + arg);
}
@Override
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof PhoneNumber))
return false;
PhoneNumber pn = (PhoneNumber) o;
return pn. lineNumber == lineNumber && pn.prefix == prefix && pn. areaCode == areaCode;
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37).append(lineNumber).append(prefix ).append(areaCode)
.toHashCode();
}
// Broken - no hashCode method!
// A decent hashCode method - Page 48
// @Override public int hashCode() {
// int result = 17;
// result = 31 * result + areaCode;
// result = 31 * result + prefix;
// result = 31 * result + lineNumber;
// return result;
// }
// Lazily initialized, cached hashCode - Page 49
// private volatile int hashCode; // (See Item 71)
//
// @Override public int hashCode() {
// int result = hashCode;
// if (result == 0) {
// result = 17;
// result = 31 * result + areaCode;
// result = 31 * result + prefix;
// result = 31 * result + lineNumber;
// hashCode = result;
// }
// return result;
// }
public static void main(String[] args) {
Map<PhoneNumber, String> m = new HashMap<PhoneNumber, String>();
m.put(new PhoneNumber(707, 867, 5309), "Jenny");
System.out.println(m.get( new PhoneNumber(707, 867, 5309)));
}
}
确定关键域,关键域指的是覆盖的equals方法中涉及到的每个域;然后,使用这些关键域,作为参数,用它们生成一个hashCode。这个可以通过HashCodeBuilder来实现,具体参照上述代码。
Item 9 覆盖equals时总要覆盖hashCode的更多相关文章
- 覆盖equals时总要覆盖hashCode
本文涉及到的概念 1.为什么重载equals方法时,要重载hashCode函数;没有重载hashCode带来的问题 2.一个对象hashCode的生成规则 1.为什么重载equals方法时 ...
- 第9条:覆盖equals时总要覆盖hashCode
在每个覆盖equals方法的类中,也必须覆盖hashCode方法.否则,会违反Object.hashCode的通用约定,从而导致该类无法结合所有基于散列的集合一起正常工作,包括HashMap,Hash ...
- Effective Java —— 覆盖equals时总要覆盖hashCode
本文参考 本篇文章参考自<Effective Java>第三版第十一条"Always override hashCode when you override equals&quo ...
- 覆盖equals 时总要覆盖hashCode(9)
2019独角兽企业重金招聘Python工程师标准>>> 1.在每个覆盖了equals 方法的类中,也必须覆盖hashCode 这是关于hashCode 的通用约定 这样可以与 基于散 ...
- 覆盖equals()时总要覆盖hashCode()
覆写如下: public class User{ private Integer id; private String userName; private String passWord; publi ...
- 【Effective Java】5、覆盖equals时总要覆盖hashcode
package cn.xf.cp.ch02.item9; import java.util.HashMap; import java.util.Map; public class PhoneNumbe ...
- EffectiveJava(9)覆盖equals是总要覆盖hashCode
覆盖equals是总要覆盖hashCode 通过散列函数将集合中不相等的实例均匀的分布在所有可能的散列值上 1.把某个非零的常数值保存在一个名为result的int类型变量中 2.对于对象中每个关键域 ...
- Item 8 覆盖equals时请遵守通用约定
在覆盖equals方法的时候,你必须要遵守它的通用约定,不遵守,写出来的方法,会出现逻辑错误.下面是约定的内容: equals方法实现了等价关系: 自反性.对于任何非null的引用值,x.eq ...
- 第8条:覆盖equals时遵守通用约定
如果不需要覆盖equals方法,那么就无需担心覆盖equals方法导致的错误. 什么时候不需要覆盖equals方法? 1.类的每个实例本质上是唯一的. 例如对于Thread,Object提供的equa ...
随机推荐
- Thunder团队第二周 - Scrum会议5
Scrum会议5 小组名称:Thunder 项目名称:爱阅app Scrum Master:苗威 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传康 ...
- Notes of the scrum meeting(12.10)
meeting time:20:00~20:30p.m.,December 10th,2013 meeting place:20号公寓前 attendees: 顾育豪 ...
- 2017-2018-2 20172323 『Java程序设计』课程 结对编程练习_四则运算
结对编程的好丽友 - 20172323 王禹涵:中缀转后缀 - 20172314 方艺雯:后缀表达式的计算 - 20172305 谭鑫:中缀表达式的输出 需求分析 能随机生成由使用者确定的任意多道四则 ...
- DAY2敏捷冲刺
站立式会议 工作安排 (1)服务器配置 (2)数据库连接 (3)页面创意 燃尽图 代码提交记录 感想 林一心:centos配置服务器真的算是一个不小的坑,目前数据库配置清楚,脚本部署好明天测试交互,还 ...
- .从列表结束中删除第N个节点
描述 给定一个链表,从列表的最后删除倒数第n个元素 例如: 给定链表:1-> 2-> 3-> 4-> 5,并且n = 2. 删除倒数第二个,链表将变为1-> 2-> ...
- Web界面和Winform界面生成,代码生成工具
在上面一篇随笔<代码生成工具之界面快速生成>介绍了代码生成工具Database2Sharp的界面生成操作,其中介绍了Web界面(包括列表界面.内容显示.内容编辑界面的生成,另外还介绍了Wi ...
- week12 201621044079 流与文件
作业12-流与文件 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 面向系统综合设计-图书馆管理系统或购物车 使用流与文件改造你的图书馆管理系统或购物车 ...
- JS DOM视频相关的知识
1.实现点击a标签改变图片时,如果a的href属性有一个目标网址,但是点击又必须跳转到另外一张图,往往会最后跳转到目标网址,可以在onclick事件函数中加入ruturn false,阻止跳转到页面. ...
- AWVS使用基础教程
什么是AWVS Acunetix Web Vulnerability Scanner(简称AWVS)是一款知名的网络漏洞扫描工具,它通过网络爬虫测试你的网站安全,检测流行安全漏洞,现已更新到10.(下 ...
- QT分析之调试跟踪系统
原文地址:http://blog.163.com/net_worm/blog/static/127702419201002004518944/ 在我们前面的分析中,经常看到qWarning()和qDe ...