Object类中hashCode()和equals()方法详解(附图)
下图是规范中要求的:
图解:比如equals相等的箭头指向hashcode相等,标示equals相等那么必有hashcode相等。另外有两个箭头指向别人的标示可能是其中之一。
//JAVA代码: public static void main(String[] args) {Object obj1 = new Object();Object obj2 = new Object();Object obj3 = obj2;System.out.println("obj1 equals obj2 ?" + obj1.equals(obj2));System.out.println("obj2 equals obj3 ?" + obj2.equals(obj3));System.out.println("obj1's hashcode: " + obj1.hashCode());System.out.println("obj2's hashcode: " + obj2.hashCode());System.out.println("obj2's hashcode: " + obj3.hashCode());} } //输出结果: obj1==obj2 ?false obj2==obj3 ?true obj1's hashcode: 12677476 obj2's hashcode: 33263331 obj3's hashcode: 33263331
也就是当我们写了一个自己的class,然后用class new了两个对象,如果在这两个对象上用equals时,此时比较的两个引用是不是一样,也就是他们的物理地址是不是一样,如果不一样的话,就会返回false. 我们实际用的时候,往往不是希望比较两个对象的物理地址是不是一样,而比较两个对象的属性等东西是不是一样,所以Object提供的方法往往不能满足我们要求。 这就需要我们覆盖Object的equals方法。
如果要覆盖Object的equals的方法,一定要满足以下几个等价关系:
1. 自反性,对于任何非null的引用值x,x.equals(x)必须反回true
2. 对称性,对于任何非null的引用值x,y,当且仅当y.equals(x)返回true时,x.equals(y),才返回true.
3. 传递性,对于任何非null的引用值x,y,z,如果x.equals(y)返回true,并且y.equals(z)返回ture,那 么x.equals(z)也必须返回true.
4. 一致性,对于任何非null的引用值x,y,只要equals比较操作的两个对象中所用的信息没有被修改,多次 调用x.equals(y)就会一致的返回true,或者一致的返回false.
5.对于任何的非null的值x,x.equals(null),必须返回false .
如果我们的程序中没有完全遵守这些约定,那么你的程式就有可能发生问题。
没有出问题的原因是,因为你的程序没有地方 直接调用 或者 间接调用 equals方法。 什么是直接调用equals ,什么是间接调用equals呢? 直接调用equals方法就是说,你显式的在你的程序中对你自己的写的对象上面调用equals方法, 间接调用呢,用一简单的例子来说,当我们平常会把一个些对象放到collection,为了不重复,我们有调用collection的contains方法,此时就间接调用了collection中对象的equals方法。
覆盖了equals的类中,也必须覆盖hashCode方法
简单的结论:当对象类没有不符合规范的override equals()和hashcode()方法的时候,两个对象做比较
- 如果equals()比较相同,那么hashcode()肯定相同。
- 如果hashcode()比较相同,那么equals()不一定相同。
众所周之,String 、Math、还有Integer、Double。。。。等这些封装类重写了Object中的equals()方法,让它不再比较句柄(引用),而是比较对象中实际包含的整数的值,即比较的是内容。
而Object的equals()方法比较的是地址值。 一般来说,如果你要把一个类的对象放入容器中,那么通常要为其重写equals()方法,让他们比较地址值而不是内容值。特别地,如果要把你的类的对象放入散列中,那么还要重写hashCode()方法;要放到有序容器中,还要重写compareTo()方法。
为什么要重写hashCode方法? 我们应该先了解java判断两个对象是否相等的规则。 在java的集合中,判断两个对象是否相等的规则是:
首先,判断两个对象的hashCode是否相等 如果不相等,认为两个对象也不相等 如果相等,则判断两个对象用equals运算是否相等 如果不相等,认为两个对象也不相等 如果相等,认为两个对象相等
我们在equals方法中需要向下转型,效率很低,所以先判断hashCode方法可以提高效率。
equals()相等的两个对象,hashcode()一定相等; equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。换句话说,equals()方法不相等的两个对象,hashcode()有可能相等。(我的理解是由于哈希码在生成的时候产生冲突造成的)。
反 过来:hashcode()不等,一定能推出equals()也不等;hashcode()相等,equals()可能相等,也可能不等。
Object类中hashCode()和equals()方法详解(附图)相关推荐
- java中hashcode()和equals()的详解[转]
今天下午研究了半天hashcode()和equals()方法,终于有了一点点的明白,写下来与大家分享(zhaoxudong 2008.10.23晚21.36). 1. 首先equals()和hash ...
- java.equal例子_Java中的== 和equals()方法详解与实例
Java中的== 和equals()方法: Java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型. byte,short,char,int,long,float,double,boo ...
- equals方法详解
目录 1.equals方法 2.重写equals方法的原则是什么 3.相等测试与继承 4.重写了euquals方法为什么还要重写hashcode? 5.如何写好一个equals方法(以下内容摘抄于Ja ...
- Object类中的两个方法——wait和notify使用总结
Object类中的wait .和 notify方法是用来处理线程的方法,既然定义在Object类中,两个方法的重要程度可见一斑: 两个方法的使用上都很复杂:通过阅读API获得更多对方法的理解: The ...
- java equals方法详解
序言:准备总结一些java基础的知识方便以后查阅,从equals入手 目录: 等于(==)详解 equals方法详解 一.等于(==)详解 先明确一点:"==" 其实是存储地址的比 ...
- python类装饰器详解-Python类中的装饰器在当前类中的声明与调用详解
我的Python环境:3.7 在Python类里声明一个装饰器,并在这个类里调用这个装饰器. 代码如下: class Test(): xx = False def __init__(self): pa ...
- php中this的使用技巧,JavaScript中this关键字使用方法详解
JavaScript中this关键字使用方法详解 在面向对象编程语言中,对于this关键字我们是非常熟悉的.比如C++.C#和Java等都提供了这个关键字,虽然在开始学习的时候觉得比较难,但只要理解了 ...
- java中迭代器要导包吗_java 中迭代器的使用方法详解
java 中迭代器的使用方法详解 前言: 迭代器模式将一个集合给封装起来,主要是为用户提供了一种遍历其内部元素的方式.迭代器模式有两个优点:①提供给用户一个遍历的方式,而没有暴露其内部实现细节:②把元 ...
- moviepy音视频剪辑:视频剪辑基类VideoClip的属性及方法详解
☞ ░ 前往老猿Python博文目录 ░ 一.概述 在<moviepy音视频剪辑:moviepy中的剪辑基类Clip详解>和<moviepy音视频剪辑:moviepy中的剪辑基类Cl ...
最新文章
- linux 系统调用 read,write和lseek 使用
- 开发日记-20190402
- Vista 下的注册 com 类失败解决方法
- 口碑网发布2010吃住玩消费风向指数
- java如何找重复数字_Java如何找出数组中重复的数字
- eax, ebx, ecx, edx, esi, edi, ebp, esp 各寄存器作用
- 我参与的一个项目总结
- Linux Frp内网穿透
- 【纯干货】4年前想解决的事情,今天才实验成功
- 设计师配色宝典!教你从零开始学配色(一)
- 架构之美第十三章-美丽的架构
- log4j2关闭debug日志
- 微星主板前置音频接口的连接说明
- Qt 获取当前屏幕分辨率
- JavaScript创建对象的方式
- 688. 骑士在棋盘上的概率(中等 动态规划)
- 浅谈iOS中关于app的优化
- linux irc 客户端,IRC 频道与客户端
- Pairwise(FCC算法)
- Spring中Bean的生命周期以及三级缓存介绍
热门文章
- k8s核心技术-Pod(镜像的拉取_重启策略_资源限制)_---K8S_Google工作笔记0022
- Sentinel降级简介_分布式系统集群限流_线程数隔离_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0038
- HBuilder工作笔记003---HBuilder 连接夜神模拟教程
- My Ruby Blog
- NLP之路-python爬虫
- Open vSwitch作为openflow交换机的启动方法
- 3d激光雷达开发(旋转和位移)
- 微型计算机体系结构的主要特点,高性能微型计算机体系结构:奔腾、酷睿系列处理器原理与应用技术...
- Linux两个网卡mac地址重复,ARP响应Linux服务器上的单个MAC地址,同一网络上有多个接口...
- ios html异步加载图片,iOS 异步加载本地图片