文档章节

Java 中的hashCode()和equals()

idoz
 idoz
发布于 2011/12/10 15:43
字数 733
阅读 237
收藏 0

此两个方法是从Object 类继承而来的,大多数时间我们都要重写这两个方法,以下是它们之间的说明:

  1. 从Object 继承过来hasCode()取得的是当前对象的内存地址的int 映射(将内存地址映射为一个int值),也就是说当我们new 两个对象时,它们的hasCode()是不同的,当然你比较equals()也是不同的。
  2. 如果重写其中的一个方法,那么必定要重写另外一个方法,因为它们之间有着重要的关系要维护
  3. 如果两个对象使用equals()方法比较结果为相同,则它们必定返回相同的hashCode()值,反之则未必;在一些体系架构下,它的寻址空间可能大于一个int的表示范围,在这种情况下,两个不同的对象有可能返回相同的hashCode值,如果你重写了hashCode()方法,你仍可以使用System.indentityHashCode()来访问这个默认值。

 

让我们来看看Object类的equals()方法吧:

public boolean equals(Object obj) { 
    return (this == obj); 
  }

这个默认的实现仅仅是比较了两个对象是否为同一个引有,而在上面我们也已说过默认的hashCode()返回的是对象内存地址的int映射。

以下是Integer类重写的equals()方法

public boolean equals(Object obj) {
    return (obj instanceof Integer 
            && intValue() == ((Integer) obj).intValue());
  }

 

同样的对于其它基本类型的装类(例如 Integer, Float, Character, 和 Boolean, 以及 String (两个String相同的话它们就要有相同的字符顺序),都重写了这一方法。

 

为什么要重写equals()和hashCode()方法呢?

如果我们从来就不将Integer当作基于hash的集合元素使用(如HashMap中的key),那么就不用重写了。如果不重写的话那么就继承自Object的,为什么Object 类要有hashCode()方法呢,那主要是因为JVM体系架构中使用hashCode()方法可以更加有效地对对象进行存储和查询操作,而单单使用equals()会增加系统的开销。

实现equals()和hashCode()方法的要求:   

  1. 对称性(Symmetry):对于两个引用a,b  a.equals(b)的话b.equals(a)
  2. 自反性(Reflexivity):对于所有的非空引用 a.equals(a)
  3. 传递性(Transitivity):如果a.equals(b) 并且b.equals(c) 则a.equals(c)
  4. 一致性(Consistency):这个特性是对于hashCode()方法来说的,两个相同的对象必须返回相同的hashCode()值     

以下给出一个示例:

class A {
    final B someNonNullField;
    C someOtherField;
    int someNonStateField;
  }

我们来重写一个equals()方法

public boolean equals(Object other) {
    // Not strictly necessary, but often a good optimization
    if (this == other)
      return true;
    if (!(other instanceof A))
      return false;
    A otherA = (A) other;
    return 
      (someNonNullField.equals(otherA.someNonNullField))
        && ((someOtherField == null) 
            ? otherA.someOtherField == null 
            : someOtherField.equals(otherA.someOtherField)));
  }

我们重写hashCode()方法

public int hashCode() { 
    int hash = 1;
    hash = hash * 31 + someNonNullField.hashCode();
    hash = hash * 31 
                + (someOtherField == null ? 0 : someOtherField.hashCode());
    return hash;
  }

这样一个一般的实现就写完成了。

未完待续。。。

© 著作权归作者所有

idoz

idoz

粉丝 12
博文 382
码字总数 192349
作品 0
郑州
私信 提问
GC复制存活的对象,内存地址会变吗?以前的引用怎么办?

问题 先执行gc方法,10S后打印数组的地址,发现没变,是不是说明复制算法不改变对象的内存地址 解读 toString打印的值现有的匿名回答是正解:题主做的实验根本没有涉及对象地址。java.lang.O...

细节探索者
02/13
44
0
用来理解 Java 编程语言的 8 个图表

很多时候,一张图比你说 1000 个字能更有效的说清楚一个问题。我们列举了 8 个关于 Java 语言的图表,或许可以让你对 Java 有着更深入的认识。 1. 字符串不变性(String Immutability) 下面的...

oschina
2013/09/23
7.9K
29
Java拾遗:001 - 重写 equals 和 hashCode 方法

重写equals方法 在Java中Object类是一个具体类,但它设计的主要目的是为了扩展,所以它的所有非final方法,都被设计成可覆盖(override)的。但任何一个子类在覆盖这些方法时都应遵守一些通用...

一别丶经年
2018/08/02
114
0
最最最常见的Java面试题总结-第一周

这里会分享一些出现频率极其极其高的面试题,初定周更一篇,什么时候更完什么时候停止。 Github地址:https://github.com/Snailclimb/Java-Guide/blob/master/面试必备/最最最常见的Java面试...

Amsour丶
2018/08/08
0
0
scala中的==、equals、eq

scala中equals方法和==是检查值是否相等,而eq方法检查的是引用是否相等。 Scala 的==与Java的有何差别 Java 里的既可以比较基本类型也可以比较引用类型。对于基本类型,Java 的==比较 值比较...

张欢19933
2018/04/27
55
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周五乱弹 —— 葛优理论+1

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @这次装个文艺青年吧 :#今日歌曲推荐# 分享米津玄師的单曲《LOSER》: mv中的舞蹈诡异却又美丽,如此随性怕是难再跳出第二次…… 《LOSER》-...

小小编辑
今天
250
8
nginx学习笔记

中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯。 是连接两个独立应用程序或独立系统的软件。 web请求通过中间件可以直接调用操作系统,也可以经过中间件把请求分发到多...

码农实战
今天
5
0
Spring Security 实战干货:玩转自定义登录

1. 前言 前面的关于 Spring Security 相关的文章只是一个预热。为了接下来更好的实战,如果你错过了请从 Spring Security 实战系列 开始。安全访问的第一步就是认证(Authentication),认证...

码农小胖哥
今天
15
0
JAVA 实现雪花算法生成唯一订单号工具类

import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;import java.util.Calendar;/** * Default distributed primary key generator. * * <p> * Use snowflake......

huangkejie
昨天
17
0
PhotoShop 色调:RGB/CMYK 颜色模式

一·、 RGB : 三原色:红绿蓝 1.通道:通道中的红绿蓝通道分别对应的是红绿蓝三种原色(RGB)的显示范围 1.差值模式能模拟三种原色叠加之后的效果 2.添加-颜色曲线:调整图像RGB颜色----R色增强...

东方墨天
昨天
11
1

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部