`
gstarwd
  • 浏览: 1540369 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JAVA中的equals()和hashCode()方法

阅读更多

Java 语言中, equals() hashCode() 两个函数的使用是紧密配合的,你要是自己设计其中一个,就要设计另外一个。在多数情况下,这两个函数是不用考虑的,直接使用它们的默认设计就可以了。但是在一些情况下,这两个函数最好是自己设计,才能确保整个程序的正常运行。最常见的是当一个对象被加入集合对象( collection object )时,这两个函数必须自己设计。更 细化的定义是:如果你想将一个对象 A 放入另一个 Collection Object B 里,或者使用这个对象 A 为查找一个元对象在 Collection Object    B 里位置的 key ,并支持是否容纳,删除 Collection Object    B 里的元对象这样的操作,那么, equals() hashCode() 函数必须开发者自己定义。其他情 况下,这两个函数是不需要定义的。

equals():

它是用于进行两个对象的比较的,是对象内容的 比较,当然也能用于进行对象参阅值的比较。什么是对象参阅值的比较?就 是两个参阅变量的值得比较,我们 都知道参阅变量的值其实就是一个数字,这个数字可以看成是鉴别不同对象的代号。两个对象参阅值的比较,就是两个数字的比较,两个代号的比较。这种比较是默 认的对象比较方式,在 Object 这个对象中,这种方式就已经设计好了。所以你也不用自己来重写,浪费不必要的时间。

对象内容的比较才是设计 equals() 的真正目的, Java 语言对 equals() 的要求如下,这些要求是必须遵循的。否则,你就不该浪费时间:

对称性:如果 x.equals(y) 返回是 “true” ,那么 y.equals(x) 也应该返回是 “true”

反射性: x.equals(x) 必须返回是 “true”

类推性:如果 x.equals(y) 返回是 “true” ,而且 y.equals(z) 返回是 “true” ,那么 z.equals(x) 也应该返回是 “true”

还有一致性:如果 x.equals(y) 返回是 “true” ,只要 x y 内容一直不变,不管你重复 x.equals(y) 多少次,返回都是 “true”

任何情况下, x.equals(null) ,永远返回是 “false” x.equals( x 不同类型的对象 ) 永远返回是 “false”

hashCode():
这个函数返回的就是一个用来进行 hash 操作的整型代号,请不要把这个代号和前面所说的参阅变量所代表的代号弄混了。后者不仅仅是个代号还具有在内存中才查找对 象的位置的功能。 hashCode() 所返回的值是用来分类对象在一些特定的 Collection 对象中的位置。这些对象是 HashMap, Hashtable, HashSet ,等等。这个函数和上面的 equals() 函数必须自己设计,用来协助 HashMap, Hashtable, HashSet ,等等对自己所收集的大量对象进行搜寻和定位。

这些 Collection 对象究竟如何工作的,想象每个元对象 hashCode 是一个箱子的 编码,按照编码,每个元对象就是根据 hashCode() 提供的代号归入相应的箱子里。所有的箱子加起来就是一个 HashSet HashMap ,或 Hashtable 对象,我们需要寻找一个元对象时,先看它的代码,就是 hashCode() 返回的整型值,这样我们找到它所在的箱子,然后在箱子里,每 个元对象都拿出来一个个和我们要找的对象进行对比,如果两个对象的内容相等,我们的搜寻也就结束。这种操作需要两个重要的信息,一是对象的 hashCode() ,还有一个是对象内容对比的结果。

hashCode()
的返回值和 equals() 的关系如下:

如果 x.equals(y) 返回 “true” ,那么 x y hashCode() 必须相等。

如果 x.equals(y) 返回 “false” ,那么 x y hashCode() 有可能相等,也有可能不等。


为什么这两个规则是这样的,原因其实很简单,拿 HashSet 来说吧, HashSet 可以拥有一个或更多的箱子,在同一个箱子中可以有一个 或更多的独特元对象( HashSet 所容纳的必须是独特的元对象)。这个例子说明一个元对象可以和其他不同的元对象拥有相同的 hashCode 。但是一个 元对象只能和拥有同样内容的元对象相等。所以这两个规则必须成立。 ( 在实际的某个集合对象如 HashSet set.contains(object o); 时,是先通过 hashcode() 找到 箱子 ,在根据 equals 判断对象内容 是否相等,从而判断集合对象是否包含某个元对象)

设计这两个函数所要注意到的:
如果你设计的对象类型并不使用于 Collection 对象,那么没有必要自己再设计这两个函数的处理方式。这是正确的面向对象设计方法,任何用户一时用不到的功能,就先不要设计,以免给日后功能扩展带来麻烦。

如果你在设计时想别出心裁,不遵守以上的两套规则,那么劝你还是不要做这样想入非非的事。我还没有遇到过哪一个开发者和我说设计这两个函数要违背前面说的两个规则,我碰到这些违反规则的情况时,都是作为设计错误处理。

当一个对象类型作为 Collection 对象的元对象时,这个对象应该拥有自己处理 equals() ,和 / 或处理 hashCode() 的设计,而且要遵守前面所说 的两种原则。 equals() 先要查 null 和是否是同一类型。查同一类型是为了避免出现 ClassCastException 这样的异常给丢出来。查 null 是为了避免出现 NullPointerException 这样的异常给丢出来。

如果你的对象里面容纳的数据过多,那么这两个函数 equals() hashCode() 将会变得效率低。如果对象中拥有无法 serialized 的数据, equals() 有可能在操作中出现错误。想象 一个对象 x ,它的一个整型数据是 transient 型(不能被 serialize 成二进制数据流)。然而 equals() hashCode() 都有依靠 这个整型数据,那么,这个对象在 serialization 之前和之后,是否一样?答案是不一样。因为 serialization 之前的整型数据是有效的 数据,在 serialization 之后,这个整型数据的值并没有存储下来,再重新由二进制数据流转换成对象后,两者(对象在 serialization 之前和之后)的状态已经不同了。这也是要注意的。

知道以上这些能够帮助你:
1.
进行更好的设计和开发。
2.
进行更好的测试案例开发。
3.
在面试过程中让面试者对你的学识渊博感到满意。

Hibernate 中, POJO 类要重写 hashcode() 方法和 equals() 方法。为什么呢?

1 ,重点是 equals ,重写 hashCode 只是技术要求(为了提高效率)

2 ,为什么要重写 equals 呢,因为在 java 的集合框架中,是通过 equals 来判断两个对象是否相等的

3 ,在 hibernate 中,经常使用 set 集合来保存相关对象,而 set 集合是不允许重复的,但是下面的程序,判断一下运行结果:

    Set user = new HashSet();
    user.add(new Address("http://hi.baidu.com/yangwen_yw"));
    user.add(new Address("http://hi.baidu.com/yangwen_yw"));
    System.out.println(user.size());

上面程序的运行结果取决于 Address 类是否重写了 equals 方法。

如果没有重写,默认 equals 是比较地址,那么这两个 address 对象不一样,输出 2 ,意味着 hibernate 会认为这是两个对象,再接下来的持久化过程中可能会出错。

如果重写了 equals ,比如按照主键( address 空间地址)比较,那么这两个对象是一样的,输出 1

分享到:
评论

相关推荐

    Java中equals,hashcode和==的区别

    "Java中equals、hashcode和==的区别" Java 中 equals、hashcode 和==的区别是 Java 编程语言中一个经常遇到的问题。这三个概念都是用来比较对象的,但是它们之间存在着本质的区别。 首先,==号是Java中的一个...

    重写equals和hashcode方法_equals_重写equals和hashcode方法_

    在Java编程语言中,`equals()` 和 `hashCode()` 方法是Object类中的两个核心方法,所有类都默认继承自Object类。这两个方法在处理对象比较和集合操作时起着至关重要的作用。当我们创建自定义类并需要对对象进行精确...

    Java中的equals和hashCode方法详解1

    在Java编程语言中,`equals()`和`hashCode()`方法是对象的基本组成部分,它们主要用于对象的比较和存储。这两个方法在`java.lang.Object`类中定义,因此所有的Java类都默认继承了这两个方法。然而,根据具体的应用...

    Java重写equals及hashcode方法流程解析

    Java中的equals和hashCode方法是两个非常重要的方法,它们都是Object类中的方法。在实际开发中,正确地重写这两个方法对于确保程序的正确性和性能至关重要。下面,我们将详细地介绍Java重写equals及hashCode方法的...

    Java重写equals同时需要重写hashCode的代码说明

    Java重写equals同时需要重写hashCode的代码说明,以及如何重写hashCode方法,此代码演示按照effective java书籍说明的重写思路。代码中演示了使用集合存储对象,并且对象作为key,需重写equals和hashCode.

    Java理论与实践:hashCode()和equals()方法

    本文介绍了Java语言不直接支持关联数组,可以使用任何对象作为一个索引的数组,但在根Object类中使用 hashCode()方法明确表示期望广泛使用HashMap。理想情况下基于散列的容器提供有效插入和有效检索;直接在对象模式...

    ordinary-zhang#java#equals和hashcode方法详解1

    1.概述 2.为什么重写equels方法要重写hashcode方法 3.例子

    equals与hashCode方法讲解

    equals 方法和 hashCode 方法是 Java 语言中两个重要的方法,它们都是在 Object 类中定义的。equals 方法用于比较两个对象是否相等,而 hashCode 方法用于返回对象的哈希码。 在 Java 的 Object 类中,equals 方法...

    关于Object中equals方法和hashCode方法判断的分析

    在 Java 中,Object 类提供了两个重要的方法:equals 方法和 hashCode 方法。这两个方法都是用于比较两个对象是否相等的,但它们的实现机理和作用域却有所不同。 equals 方法是用于比较两个对象是否相同的。它的...

    Java容器集合(equals 和 hashCode+基础数据结构+ArrayList+Vector和LinkedList)

    其中,equals和hashCode方法是Java容器集合中两个非常重要的方法,本文将详细介绍这两个方法,并结合ArrayList、Vector和LinkedList三个常见的容器集合。 一、equals方法 equals方法是Java中用于比较两个对象是否...

    java中hashcode()和equals()方法详解

    在Java编程语言中,`hashCode()`和`equals()`方法是非常重要的概念,它们不仅对于深入理解Java内存管理至关重要,也是实现自定义类的关键部分之一。本文将详细介绍这两个方法的工作原理、使用场景以及它们之间的关系...

    Java equals 方法与hashcode 方法的深入解析.rar

    在Java编程语言中,`equals()`方法和`hashCode()`方法是两个非常重要的概念,它们主要用于对象的比较和哈希表的高效运作。本解析将深入探讨这两个方法的用途、实现原理以及它们之间的关联。 首先,`equals()`方法是...

    equals与hashCode在实际开发中的重写写法

    在Java编程语言中,`equals()` 和 `hashCode()` 方法是两个非常重要的成员,尤其是在处理对象比较和集合操作时。这两个方法通常与`Object`类中的默认实现相关联,但为了在实际开发中实现正确的对象比较和哈希表操作...

    java中hashcode和equals的详解.pdf

    Java 中的 hashCode 和 equals 方法详解 本文详细介绍了 Java 中的 hashCode 和 equals 方法,探讨了这两个方法的作用、实现机制和使用场景。通过对 hashCode 和 equals 方法的深入分析,我们可以更好地理解 Java ...

    equals,hashcode,toString

    在Java编程语言中,`equals()`, `hashCode()` 和 `toString()` 是三个非常重要的方法,它们主要用于对象的比较、哈希存储以及打印对象信息。这三个方法是Java对象的基础特性,对于理解和开发高质量的Java程序至关...

    Java_重写equals()和hashCode()

    在Java编程语言中,`equals()` 和 `hashCode()` 方法是对象的基本组成部分,它们在很多场景下都发挥着至关重要的作用。这两个方法与对象的相等性比较和哈希表(如HashMap、HashSet)的运作紧密相关。这篇博客将深入...

    探索Java中的equals()和hashCode()方法_动力节点Java学院整理

    Java中的equals()和hashCode()方法详解 Java中的equals()和hashCode()方法是两个重要的方法,它们都是从Object类中继承过来的。equals()方法用于比较两个对象的值是否相等,而hashCode()方法用于计算对象的哈希码。...

    关于hashCode()和equals()的本质区别和联系

    Java 中的每个对象都有 hashCode() 和 equals() 方法,这两个方法的正确实现对于 Java 开发人员来说是非常重要的。本文将详细介绍 hashCode() 和 equals() 的本质区别和联系,并探讨在创建 Java 类时如何定义这些...

    java集合——Java中的equals和hashCode方法详解

    在Java编程语言中,`equals()` 和 `hashCode()` 方法是Object类中定义的基本方法,所有类都默认继承自Object类,因此每个Java对象都有这两个方法。这两个方法在处理集合类,尤其是Set接口的实现(如HashSet)时起着...

Global site tag (gtag.js) - Google Analytics