关键词:
- 在应用程序的执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法都必须始终如一地返回同一个整数。在同一个应用程序的多次执行过程中,每次执行所返回的整数可以不一致。
- 如果两个对象根据equals(Object)方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode方法都必须产生同样的整数结果。
- 如果两个对象根据equals(Object)方法比较是不相等的,那么调用这两个对象中任意一个对象的hashCode方法,则不一定要产生不同的整数结果。给不相等的对象产生截然不同的整数结果,有可能提高散列表的性能。
import java.util.*; 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))); } }
- 把某个非0的常数值,比如17,保存在一个名为result的int类型的变量中。
- 对于对象中的每个关键域f,做如下操作:
- 为该域计算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方法。每个元素计算出来的hashCode,使用2.2中的公式,将hashCode组合起来。
- 为该域计算int类型的哈希值c:
private final short areaCode; private final short prefix; private final short lineNumber; @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; } // A decent hashCode method - Page 48 @Override public int hashCode() { int result = 17; result = 31 * result + (int)areaCode; result = 31 * result + (int)prefix; result = 31 * result + (int)lineNumber; return result; }
java对象覆盖equals时总要覆盖hashcode
在每个覆盖了equals方法的类中,也必须覆盖hashCode方法。 hashCode的通用约定: 1在程序的执行过程中,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法必须始... 查看详情
覆盖equals时总要覆盖hashcode
Object条约规定:相等的对象必须具有相同的散列码hashCode假如将只覆盖equals方法,没覆盖hashCode方法的类用于HashMap中,将会出现问题,会出现get()方法返回时不是同一个对象这就相当于将对象put进一个散列桶,却在另一个散列桶ge... 查看详情
effectivejava5覆盖equals时总要覆盖hashcode
packagecn.xf.cp.ch02.item9;importjava.util.HashMap;importjava.util.Map;publicclassPhoneNumber{privatefinalshortareaCode;privatefinalshortprefix;privatefinalshortlineNumber;publicPhoneNumber(intareaCod 查看详情
effectivejava第九条:覆盖equals时总要覆盖hashcode(代码片段)
先来看一个例子:PhoneNumer类publicclassPhoneNumberprivatefinalintareaCode;privatefinalintprefix;privatefinalintlineNumber;publicPhoneNumber(intareaCode,intprefix,intlineNumber)rangeCheck(areaCode,999, 查看详情
java:effectivejava学习笔记之覆盖equals时总要覆盖hashcode(代码片段)
Java覆盖equals时总要覆盖hashcode覆盖equals时总要覆盖hashcode1.什么是hashcode方法?2.hashcode相等与对象相等之间的关系:(保证设计是规范的前提下)3.为什么要覆盖hashcode3.1、覆盖equals时总要覆盖hashCode3.2、如何在覆盖... 查看详情
java实战源码解析为什么覆盖equals方法时总要覆盖hashcode方法(代码片段)
1、背景知识本文代码基于jdk1.8分析,《Java编程思想》中有如下描述:另外再看下Object.java对hashCode()方法的说明:/***Returnsahashcodevaluefortheobject.Thismethodis*supportedforthebenefitofhashtablessuchasthoseprovidedby*& 查看详情
java实战源码解析为什么覆盖equals方法时总要覆盖hashcode方法(代码片段)
1、背景知识本文代码基于jdk1.8分析,《Java编程思想》中有如下描述:另外再看下Object.java对hashCode()方法的说明:/***Returnsahashcodevaluefortheobject.Thismethodis*supportedforthebenefitofhashtablessuchasthoseprovidedby*& 查看详情
effectivejava目录
...用的方法覆盖equals时请遵守通用约定覆盖equals时总要覆盖hashCode始终要覆盖toString谨慎地覆盖clone考虑实现Comparabl 查看详情
为啥 StringBuffer/StringBuilder 不覆盖 equals 或 hashCode?
】为啥StringBuffer/StringBuilder不覆盖equals或hashCode?【英文标题】:WhydoesStringBuffer/StringBuildernotoverrideequalsorhashCode?为什么StringBuffer/StringBuilder不覆盖equals或hashCode?【发布时间】:2012-06-2204:17:58【问题描述】:为什么StringBuffer/StringBu 查看详情
为啥我需要覆盖 Java 中的 equals 和 hashCode 方法?
】为啥我需要覆盖Java中的equals和hashCode方法?【英文标题】:WhydoIneedtooverridetheequalsandhashCodemethodsinJava?为什么我需要覆盖Java中的equals和hashCode方法?【发布时间】:2022-01-0303:47:55【问题描述】:最近我通读了这个DeveloperWorksDocumen... 查看详情
为啥我需要覆盖 Java 中的 equals 和 hashCode 方法?
】为啥我需要覆盖Java中的equals和hashCode方法?【英文标题】:WhydoIneedtooverridetheequalsandhashCodemethodsinJava?为什么我需要覆盖Java中的equals和hashCode方法?【发布时间】:2019-01-2205:47:01【问题描述】:最近我通读了这个DeveloperWorksDocumen... 查看详情
equals()和hashcode()必须同时覆盖的原因
...候,一种比较常见的覆盖就是覆盖Object中的equals()方法和hashCode()方法。如果不这样做的话,就很可能违反Object.hashCode()的通用约定,从而在利用自己建的类构建需要Hash化的集合的正常工作。其中有一条约定很重要:如果两个对象... 查看详情
覆盖 Java 中的 hashCode() 和 equals() 方法
】覆盖Java中的hashCode()和equals()方法【英文标题】:OverwritingthehashCode()andequals()methodinJava【发布时间】:2020-06-0912:30:51【问题描述】:正如标题所示,我的问题与重写hashCode()和equals()方法有关。但是,这也不完全正确,我只是不知... 查看详情
在 Java 中覆盖 equals 和 hashCode 时应该考虑哪些问题?
】在Java中覆盖equals和hashCode时应该考虑哪些问题?【英文标题】:WhatissuesshouldbeconsideredwhenoverridingequalsandhashCodeinJava?【发布时间】:2010-09-0620:31:11【问题描述】:覆盖equals和hashCode时必须考虑哪些问题/陷阱?【问题讨论】:【参... 查看详情
仅使用一个变量覆盖 HashCode() 的正确方法是啥?
】仅使用一个变量覆盖HashCode()的正确方法是啥?【英文标题】:WhatisthecorrectwaytooverrideHashCode()usingonlyonevariable?仅使用一个变量覆盖HashCode()的正确方法是什么?【发布时间】:2022-01-1416:32:20【问题描述】:我目前正在尝试学习如... 查看详情
hashcode与equals的区别与联系
...equals方法用于比较对象的内容是否相等(覆盖以后)2、hashcode方法只有在集合中用到3、当覆盖了equals方法时,比较对象是否相等将通过覆盖后的equals方法进行比较(判断对象的内容是否相等)。4、将对象放入到集合中时,首先... 查看详情
intellijidea中怎么覆盖tostring(),hashcode(),equals()?
...ject类的子类。这些类都或继承或覆盖了Object类中的equal,hashCode和toString方法。在自定义类的时候,为了实现比较、在集合中查找、显示类信息等功能,也需要用到这些方法,默认情况下这些方法都继承自Object,但有的时候需要... 查看详情
hashset源码分析(代码片段)
...储键值对,Hashset仅存储对象。HashSet使用成员对象来计算hashcode值。2.原理在《Headfistjava》一书中有描述:当你把对象加入HashSet时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他加入的对象的hashcode值作比... 查看详情