`
kenniz
  • 浏览: 5305 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
社区版块
存档分类
最新评论

Java中覆盖hashCode的约定和简单方法

    博客分类:
  • Java
阅读更多

Object中关于hasdCode的通用约定:

 

1. 在应用程序的执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法都必须始终如一地返回同一个整数。在同一个应用程序的多次执行过程中,每次执行所返回的整数可以不一致。
2. 如果两个对象根据equals(Object)方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode方法都必须产生相同的整数结果。
3. 如果两个对象根据equals(Object)方法比较是不相等的,那么调用这两个对象中任意一个对象的hashCode方法,则不一定要产生不同的整数结果。但是程序员应该知道,给不相等的对象产生截然不同的整数结果,有可能提高Hash table的性能。

 

一个好的散列函数通常倾向于“为不相等的对象产生不相等的散列码”。理想情况下,散列函数应该把集合中不相等的实例均匀地分布到所有可能的散列值上。要想完全达到这种理想的情况是非常困难的。幸运的是,相对接近这种理想情形则并不太困难。下面给出一种简单的解决办法:

1. 把某个非零的常数值,比如说17,保存在一个名为result的int类型的变量中。
2. 对于对象中的每个关键域f (指quals方法中涉及的每个域),完成以下步骤:
    a. 为该域计算int类型的散列码c:
        1) 如果该域是boolean类型,则计算(f ? 1 : 0)。
        2) 如果该域是byte, char, short或者int类型,则计算(int)f。
        3) 如果该域是long类型,则计算(int)(f^(f>>>32))。
        4) 如果该域是float类型,则计算Float.floatToIntBits(f)。
        5) 如果该域是double类型,则计算Double.doubleToLongBits(f),然后按照步骤2.a.3,为得到的long类型值计算散列值。
        6) 如果该域是一个对象的引用,并且该类的equals方法通过递归地调用equals的方式来比较这个域,则同样为这个域递归地调用hashCode。如果需要更复杂的比较,则为这个域计算一个“范式(canonical representation)”,然后针对这个范式调用hashCode。如果这个域的值为null,则返回0 (或者其他某个整数,但通常是0)。
        7) 如果该域是一个数组,则要把每一个元素当作单独的域来处理。也就是说,递归地应用上述规则,对每个重要的元素计算一个散列码,然后根据步骤2.b中的做法把这些散列值组合起来。如果数组域中的每个元素都很重要,可以利用发行版本1.5中增加的其中一个Arrays.hashCode方法。
    b. 按照下面的公式,把步骤2.a中计算得到的散列码c合并到result中:
        result = 31 * result + c;
3. 返回result。
4. 写完了ashCode方法之后,问问自己“相等的实例是否都具有相等的散列码”。要编写单元测试来验证你的推断。如果相等的实例有着不同的散列码,则要找出原因,并修正错误。

分享到:
评论

相关推荐

    如何正确实现Java中的HashCode共6页.pdf.z

    在Java编程语言中,`hashCode()`方法是每个对象都继承自`Object`类的一个关键功能。这个方法的主要目的是为对象生成一个整数哈希码,它通常用于优化数据结构,如哈希表(如`HashMap`和`HashSet`)。本教程“如何正确...

    学习Object类——为什么要重写equeals和hashcode方法

    此外,Object 类的设计是为了扩展,它提供了一些非 final 方法,如 equals、hashCode、toString、clone 和 finalize,这些方法都有通用的约定,需要在子类中被覆盖(override)。如果不遵守这些约定,依赖这些约定的...

    Java Object类认识

    - 在重写`equals()`时,通常也需重写`hashCode()`,以保持两个方法的一致性,遵循equals和hashCode约定,确保当两个对象相等时,它们的哈希码也应该相等。 总结来说,理解`Object`类及其提供的方法是Java开发的基础...

    为什么在重写 equals方法的同时必须重写 hashcode方法

    在 Java 中,`equals` 和 `hashCode` 方法是 Object 类中的两个重要方法,它们用于比较对象的相等性。默认情况下,`equals` 方法比较的是两个对象的引用,即是否指向内存中的同一个位置,而 `hashCode` 方法则返回...

    Java基础知识面试题(2020最新版).pdf

    static修饰符主要用于创建类级别的变量和方法,它的独特之处在于不依赖于类的实例就能访问。 流程控制语句如break、continue和return各有用途,break用于跳出当前循环,continue跳过当前循环剩余部分并继续下一轮,...

    java学习资料.zip

    7. **方法覆盖(Method Overriding)**:解释方法覆盖的规则,包括访问权限的提升和重写equals()和hashCode()的重要性。 8. **设计和文档注解(Design and Documentation Annotations)**:讨论如何使用注解来提高...

    Java常见笔试、面试系列深度剖析第六讲

    本讲将深度剖析Java中的"==运算符"和"equals()方法",这两个是判断对象之间相等性的主要手段。 一、"=="运算符 "=="运算符在Java中用于比较基本类型的值是否相等,例如int、char、boolean等。对于引用类型的变量,...

    MLDN魔乐JAVA_09深入引用、this关键字、对象比较.rar

    在Java编程语言中,深入理解和熟练运用引用、`this`关键字以及对象比较是提升编程技能的关键环节。本课程“MLDN魔乐JAVA_09深入引用、this关键字、对象比较”将带你深入探讨这些核心概念。 首先,让我们来讨论...

    面试官瞬间就饱了,重写equals函数,需要重写hashCode函数吗?

    在Java编程语言中,`equals()` 和 `hashCode()` 方法是对象的基本组成部分,它们与对象的比较和哈希表(如 `HashMap`)的操作密切相关。在面试中,面试官提出的问题直指这两个方法的重要关联。 首先,`equals()` ...

    超详细的Java面试题总结(三)之Java集合篇常见问题.docx

    根据equals()和hashCode()的约定,如果两个对象相等,它们的hashcode也应相同,反之不成立。 最后,Comparable和Comparator接口用于排序。Comparable是对象本身实现的接口,通过覆盖compareTo()方法实现自然排序。...

    JAVA面试信息四.docx

    抽象类可以封装子类中重复的成员变量和方法,减少代码冗余。此外,抽象类还可以定义抽象方法,这些方法在子类中具体实现,但定义时保持一致,促进了代码的规范性和可扩展性。 `equals`和`hashCode`方法是Java对象的...

    core java达内培训资料

    子类可以覆盖父类的方法以提供新的实现,也可以增加新的属性和方法。 ### 构造器在继承中的作用 在继承结构中,子类默认调用父类的无参构造器。如果需要调用父类的其他构造器,可以通过super关键字明确指定。子类...

    Java 全栈知识点问题汇总(1).pdf

    2. 继承:继承是实现IS-A关系的方式,子类继承父类,从而获得父类的非私有属性和方法。遵循里氏替换原则,子类对象可以替换父类对象,即父类引用可以指向子类实例。例如,`Cat`可以继承自`Animal`,并使用`Animal`...

    java资源题库

    ### Java资源题库知识点解析 ...综上所述,Java资源题库中的知识点覆盖了Java语言的基础知识、面向对象特性、集合框架、多线程处理、异常管理等多个方面,对于深入理解和掌握Java编程具有重要意义。

    Java核心技术(1).pdf

    - **项04:始终覆盖hashCode**:当重写了equals方法时,必须同时重写hashCode方法以保持一致性。 - **项05:谨慎覆盖finalize**:finalize方法主要用于执行资源清理工作,但其效率低下且不可预测,应尽量避免使用。 ...

    从初面到终面:JAVA面试系列之java基础面试题及答案

    19. **Java实现多态**:通过接口、抽象类和方法重写实现。 20. **重载与重写的区别**:重载发生在同一类中,方法名相同,参数列表不同;重写发生在子类中,方法名、返回类型和参数列表都相同,但子类方法不能降低...

    (完整版)2020年最新Java面试专题答案.doc

    在Java编程语言中,面试时常会涉及到一些核心概念和技术细节,以下是一些基于提供的文件内容的详细解释: 1. **JDK与JRE的区别**: JDK(Java Development Kit)是用于开发Java应用程序的工具包,它包含了JRE...

    java面试题集重要.pdf

    由于`equals()`不相等,根据Java的约定,`hashCode()`也应返回不同的值,因此`a.hashCode() == b.hashCode()`返回`false`。 2. 程序输出分析: ```java public static void certkiller(String str) { int check = ...

    java面试题(20210925010116)[参照].pdf

    - 根据Java的约定,如果两个对象通过 `equals()` 方法比较结果为 true,那么它们的 `hashCode()` 方法应该返回相同的值。然而,两个具有相同 `hashCode()` 的对象并不意味着它们通过 `equals()` 方法比较会返回 ...

Global site tag (gtag.js) - Google Analytics