`
sungang_1120
  • 浏览: 321638 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类

Java中的equals()和hashCode()契约

 
阅读更多

java.lang.Object类中有两个非常重要的方法:

 

public boolean equals(Object obj)
public int hashCode()

 理解这两个方法非常的重要,尤其是将用户自定义的对象添加到Map中的时候。有时候就算是久经沙场的老程序员也弄不清楚该如何正确使用它们。这篇文章中,我将用一个例子让大家看看大家经常会犯的错误,然后解释equals()和hashCode()的正确的使用方法。

 

 

 

1. 常见错误:

 

import java.util.HashMap;
 
public class Apple {
    private String color;
 
    public Apple(String color) {
        this.color = color;
    }
 
    public boolean equals(Object obj) {
        if (!(obj instanceof Apple))
            return false;  
        if (obj == this)
            return true;
        return this.color == ((Apple) obj).color;
    }
 
    public static void main(String[] args) {
        Apple a1 = new Apple("green");
        Apple a2 = new Apple("red");
 
        //hashMap stores apple type and its quantity
        HashMap m = new HashMap();
        m.put(a1, 10);
        m.put(a2, 20);
        System.out.println(m.get(new Apple("green")));
    }
}

 

 

这个例子中,一个“绿苹果”的对象成功添加到hashMap中了,但是当我们要取出这个“绿苹果”的时候,却得不到这个对象,程序返回null。我们使用调试器却发现在hashMap中已经存储了这个对象。

 

 

2. hashCode()引起的问题:

这个问题是因为”hashCode()”方法没有被重写。Java中equals()和hashCode()有一个契约:

 

  • 1. 如果两个对象相等的话,它们的hash code必须相等;
  • 2. 但如果两个对象的hash code相等的话,这两个对象不一定相等。

 

Map的结构能够快速找到一个对象,而不是进行较慢的线性查找。使用hash过的键来定位对象分两步。Map可以看作是数组的数组。第一个数组的索 引就是对键采用hashCode()计算出来的值,再在这个位置上查找第二个数组,使用键的equals()方法来进行线性查找,直到找到要找的对象。

public int hashCode(){
    return this.color.length();
}

 

Object类中的hashCode()对于不同的对象返回不同的整数,所以上面的例子中,不同的对象(即使相同的类型)也返回不同的hash值。

 

Hash码就像是一个存储空间的序列,不同的东西放在不同的存储空间中。将不同的东西整理放在不同的空间中(而不是堆积在一个空间中)更高效。所以能够均匀的分散hash码是再好不过了。

 

上面错误的解决方法就是在类中增加hashCode方法。这里我仅仅使用颜色的长度来计算hash码。

 

 

 

分享到:
评论

相关推荐

    Java中的equals()和hashCode()契约Ja

    在Java中,`equals()`和`hashCode()`有一个基本的契约: 1. **自反性**:对于任何非空引用x,`x.equals(x)`应返回`true`。 2. **对称性**:如果x.equals(y)返回`true`,那么y.equals(x)也应返回`true`。 3. **传递...

    Java中的== 和equals()方法详解与实例

    在Java编程语言中,`==` 和 `equals()` 方法是用来比较对象或基本数据类型的值的。两者虽然在外观上相似,但...同时,为了保持一致性,通常也会重写 `hashCode()` 方法,以遵循 `equals()` 和 `hashCode()` 的契约。

    Java Interview Questions for 5 years Experience.pdf

    hashCode()和equals()契约的重要性在于,它们之间的关系决定了对象在集合中的唯一性。 7. classpath变量和path变量的区别 classpath变量和path变量都是Java的环境变量,但它们之间存在一些区别。classpath变量用于...

    Effective.Java3rd.zip

    20. **避免在equals()中抛出异常**:equals()方法应始终返回布尔值,不应该抛出异常,以遵循其契约。 21. **理解并使用equals()和hashCode()合同**:equals()和hashCode()必须一致,如果两个对象相等,它们的...

    100道经典java面试题

    Java 面试中,了解和掌握核心概念是至关重要的,以下是对这些知识点的详细解析: 1. **面向对象和面向过程的区别** - **面向过程编程**:它以过程为中心,强调步骤的顺序执行。面向过程的优点在于性能较高,因为...

    java类的重用课件

    Object 类是所有 Java 类的超类,提供了一些基础的方法,如 `toString()`、`equals()` 和 `hashCode()`。在 `Employee` 和 `Manager` 类中,`toString()` 方法用于以字符串形式表示对象,这展示了如何覆盖 Object 类...

    HE-Collection:HE集合-独立于hashCode()和equals(Object)-开源

    HE-Collection的实现是为了将对象存储在集合中,该制动使equals(Object)和hashCode()之间的契约失效,即使HE-Collections包含不遵守契约的对象,其行为也可以预测。 名称“ HE”代表哈希码和等于。

    java非常基础面试题

    2、**Java接口**:接口在Java中用于定义一种契约,规定实现接口的类必须遵循的规则。接口可以解决单继承的问题,提供多继承的替代方案。定义接口有利于代码的规范和扩展,使得代码更易于维护。例如,KFC实体店可以...

    麻省理工18年春软件构造课程阅读15-相等-1

    在Java中,`==`运算符用于检查引用相等,而`equals()`方法用于检查对象相等。默认的`equals()`方法在`Object`类中定义,它简单地比较两个对象的引用。但是,当我们定义自定义类时,如`Duration`,通常需要重写`...

    Java面试基础题秘籍.pdf

    1. Object类中的equals()、hashCode()、toString()、clone()方法是所有Java类的基础。 2. 序列化允许将对象的状态保存到磁盘或在网络中传输,transient关键字用于标记不参与序列化的成员。 3. 内部类可以是成员内部...

    Java面试宝典Beta5.0.pdf

    本文将根据提供的文件内容,梳理和详述Java面试中常见的知识点。 ### 第一章 内容介绍 在面试宝典的第一章内容介绍中,虽然没有给出具体内容,但是可以推测这将是宝典的概览或目录部分,为面试者提供对后续章节...

    Java基础 121例练习示例

    18. **equals()与hashCode()**: `equals()`比较两个对象是否相等,`hashCode()`返回对象的哈希值,主要用于集合中的查找。 19. **Comparable与Comparator**: `Comparable`接口用于对象自比较,`Comparator`接口则...

    java源码总结-Effective-Java-3E:有效Java第三版的源代码示例和摘要的回购

    5. **equals()与hashCode()**:遵循 equals 和 hashCode 同步原则,确保当两个对象相等时,它们的哈希码也必须相等。同时,书中指出重写这两个方法时应避免出现循环引用。 6. **继承(Inheritance)**:强调慎用...

    Effictive Java

    这些规则不仅包含了Java平台开发者们的经验总结,还指出了在编码过程中应该做什么以及不应该做什么,以便于产出高质量的代码。 #### 二、创建与销毁对象 ##### Item1:考虑提供静态工厂方法而不是构造器 - **目的**...

    Java常见笔试、面试题目深度剖析

    - **equals()与hashCode()**:在"相等性(==及equals方法)详解.swf"中,会深入讨论这两个方法的区别和何时重写它们。 3. **异常处理** - **try-catch-finally**:理解如何捕获和处理异常,以及finally块的作用。...

    Java 22道基础面试题.docx

    Java是一种广泛使用的面向对象的编程语言,其强大的功能和灵活性在IT行业中占据着重要的地位。以下是一些基于Java基础知识的面试题解析: 1. Java的基本数据类型分为两大类:原始类型(Primitive Types)和引用类型...

    JPL_Coding_Standard_Java

    10. **R10:同时定义equals()和hashCode()方法** - 如果重写了`equals()`方法,则也应该重写`hashCode()`方法。 - 这样可以确保当两个对象相等时,它们具有相同的哈希码。 11. **R11:添加新字段时重新定义equals...

    程序员需要经常刷题吗-simple-java-zh-CN:SimpleJava是Java常见问题的集合。中文翻译

    hashCode() 和 equals() 之间的契约 Java是按引用还是按值传递对象? 迭代与递归 ##3。 类和接口 什么是实例初始化器? 字段不能被覆盖? 继承与组合 如何使用 Java 枚举? 有多少种内部类? 什么是内部接口? 子类...

    Java编程规则

    当继承一个类时,重写父类的方法(如`equals()`、`hashCode()`、`toString()`等)是一个常见的需求。为了确保子类能正确地覆盖这些方法,需理解Java的继承机制与多态特性。同时,实现`Cloneable`和`Serializable`...

Global site tag (gtag.js) - Google Analytics