Java equals()和hashCode()

介绍:

Java Object类提供了方法的基本实现– hashCode()equals()。 这些方法非常有用,尤其是在使用Collection框架时。 哈希表实现依赖于这些方法来存储和检索数据。

在本教程中,我们将学习hashCode()equals()之间的协定它们的默认实现)。 我们还将讨论何时以及如何覆盖这些方法。

默认行为:

首先让我们看一下这些方法的默认实现:

存在于Object类中的equals()方法只是比较对象引用:

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

因此,默认情况下, obj1.equals(obj2)obj1 == obj2相同。

equals()方法比较诸如String等的类的实际值,因为它们在相应的类中被覆盖。

JDK中hashCode()方法的签名为:

public native int hashCode();

在这里, native关键字表示该方法是使用JNI (Java本机接口)以本机代码实现的。

hashCode()方法返回一个int类型。 默认情况下,返回值表示对象存储器地址。

实施原则:

在覆盖equals()hashCode()方法之前,我们先来看一下准则:

1. equals():   我们对equals()方法的实现必须是:

  • 反身:对于任何参考值objobj.equals(obj)应该返回true
  • 对称:对于参考值obj1obj2 ,如果obj1.equals(obj2)true,obj2.equals(obj2)也应返回true
  • 传递性:对于值OBJ1参考,OBJ 2和 OBJ 3,如果obj1.equals(OBJ 2) 真实 ,obj2.equals(OBJ 3) ,那么obj1.equals(OBJ 3)也应该返回true
  • 一致:只要我们没有更改实现, equals()方法的多次调用必须始终返回相同的值

2. hashCode():实现hashCode()时,必须考虑以下几点:

  • 在一次执行中, hashCode()的多次调用必须返回相同的值,前提是我们不更改equals()实现中的属性
  • 相等的对象必须返回相同的hashCode()
  • 两个或更多不相等的对象可以具有相同的hashCode()

尽管在覆盖这些方法时要牢记上述所有原则,但是其中有一个流行的规则:

对于两个对象obj1obj2

  • 如果obj1.equals(obj2),obj1.hashCode()= obj2.hashCode()必须为true
  • 但是,如果obj1.hashCode()== obj2.hashCode() ,则obj1.equals(obj2)可以返回truefalse,即obj1obj2可能相等或不相等

这通常被称为equals()hashCode()契约。

为什么覆盖

hashCode()equals()方法在基于哈希表的实现中存储和检索元素方面起着重要作用。 hashCode()确定给定项映射到的存储桶。 在存储桶中, equals()方法用于查找给定的条目。

假设我们有一个Employee类:

public class Employee {private int id;private String name;//constructors, getters, setters, toString implementations}

还有一个存储Employee作为键的HashMap

Map<Employee, Integer> map = new HashMap<>();map.put(new Employee(1, "Sam"), 1);
map.put(new Employee(2, "Sierra"), 2);

现在我们已经插入了两个条目,让我们尝试一个containsKey()检查:

boolean containsSam = map.containsKey(new Employee(1, "Sam")); //false

尽管我们有Sam的条目,但是containsKey()返回false 。 这是因为我们尚未覆盖equals()hashCode()方法。 默认情况下, equals()只会进行基于引用的比较。

覆盖

根据Javadocs:

当我们覆盖equals()方法时,我们还必须覆盖hashCode()方法。

这将有助于避免违反equals-hashCode合同。

请注意,如果我们违反合同,编译器不会抱怨,但是当我们将此类对象作为键存储在HashMap中时,最终可能会遇到意外行为。

我们可以使用IDE的功能快速覆盖这些方法。 使用Eclipse时,我们可以转到Source-> Generate hashCode()和equals()。 让我们看看为Employee类生成的实现:

public class Employee {...@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + id;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Employee other = (Employee) obj;if (id != other.id)return false;if (name == null) {if (other.name != null)return false;} else if(!name.equals(other.name))return false;return true;}
}

显然,相同的字段已用于实现equals()hashCode()方法,以与合同保持一致。

最佳做法:

使用equals()hashCode()时应遵循的一些最佳实践包括:

  • 实现hashCode()以在各个存储桶之间平均分配项目。 这样做的目的是最大程度地减少碰撞次数,从而获得良好的性能
  • 对于equals()hashCode()实现,我们应该使用相同的字段
  • HashMap中将不可变对象作为键,因为它们支持缓存哈希码值
  • 使用ORM工具时,请始终使用getter代替hashCode()equals()方法定义中的字段。 那是因为有些字段可能是延迟加载的

结论:

在本教程中,我们首先研究了equals()hashCode()方法的默认实现。 稍后,我们讨论了何时以及如何覆盖这些方法。

成为第一个发表评论的人。

翻译自: https://www.javacodegeeks.com/2019/05/java-equals-hashcode.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/342859.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于CSMA -CA协议的无线星型网络的应用案例介绍

1、CSMA/CA特点 在无线网络通信中&#xff0c;一种被称为CSMA/CA的协议解决了上诉数据冲突问题&#xff0c;CSMA&#xff08;Carrier Sense Multiple Access&#xff09;&#xff0c;中文为冲突避免的载波侦听多路访问&#xff0c;具体工作方式为&#xff0c;发送数据前&#x…

4G物联网网关和工业路由器的区别

网关和路由器是数据通信行业被广泛使用的通信设备&#xff0c;它们都是网络连接的组成部分。那么&#xff0c;4G物联网网关和传统工业路由器有哪些区别呢&#xff1f;接下来飞畅科技的小编就来为大家详细介绍下4G物联网网关和工业路由器的区别&#xff0c;一起来看看吧&#xf…

服务器系统日志有哪些centos,CentOS 分析服务器日志命令

# 分析日志文件下 2012-05-04 访问页面最高 的前20个 URL 并排序cataccess.log |grep 04/May/2012| awk {print $11}|sort|uniq -c|sort -nr|head -20# 查询受访问页面的URL地址中 含有 www.abc.com 网址的 IP 地址cataccess_log | awk ($11~/www.abc.com/){print $1}|sort|uni…

基于Modbus RTU协议的开关量控制采集简介

一、什么是开关量控制采集 所谓的开关量控制采集就是通过458/232接口发送控制命令&#xff0c;实现读取开关量输入或者控制开关量输出的通断。 二、开关量输入采集和开关量输出控制 1. 开关量输入采集就是将一个开关信号直接接入到开关量控制采集设备输入端口&#xff0c;而…

【渝粤教育】国家开放大学2018年春季 4992T农村文化建设 参考试题

试卷代号&#xff1a;4992 &#xff08;中央广播电视大学&#xff09;2018年春季学期“开放专科”期末考试 农村文化建设 试题 2018年7月 一、单项选择题&#xff08;每题3分&#xff0c;共30分&#xff09; 1&#xff0e;“观乎天文&#xff0c;以察时变&#xff1b;观乎人文&…

浅谈开关量采集回路的设计及交流干扰问题解决方案

开关量采集回路选用光耦隔离&#xff0c;光耦作为电路之间的信号传输&#xff0c;使前端与负载完全隔离&#xff0c;增加安全性&#xff0c;减少电路干扰。该回路的运行质量直接影响着保护动作的准确性&#xff0c;所以需要采取一些电路的保护措施增加开关量采集回路的安全可靠…

怎么讲服务器上的文件装进电脑,怎么把电脑文件放进云服务器

怎么把电脑文件放进云服务器 内容精选换一换Winscp无法连接到服务器。SSH连接工具例如Xshell可以正常连接云服务器。其他SSH工具连接云服务器正常&#xff0c;但是Winscp无法连接到服务器。说明SSH服务是没有问题的&#xff0c;Winscp连接基于的是SFTP协议。查看/etc/ssh/sshd_…

飞畅 8口RS-485集线器产品性能参数介绍

8口RS-485集线器&#xff0c;具有1路RS-485转8路RS-485功能&#xff0c;DC9~48V供电&#xff0c;DIN导轨安装&#xff0c;在工业自动通信中&#xff0c;可以解决多个距离比较远的R485设备连接。那么&#xff0c;什么是八口RS-485集线器&#xff1f;8口RS-485集线器产品性能参数…

【渝粤教育】国家开放大学2018年春季 7407-21T药物治疗学(本) 参考试题

试卷代号&#xff1a;7407 座位号 2017-2018学年度第二学期期末考试 药物治疗学&#xff08;本&#xff09;试题 2018年5月 一.填空题&#xff08;每空2分&#xff0c;共40分&#xff09; 1.药物进行生物转化的主要器官为___________、催化转化的酶简称______________ 。 2. 胃…

浅谈蓝牙“嗅探”功能设计

BLE&#xff08;Bluetooth Low Energy&#xff09;即低功耗蓝牙技术&#xff0c;通讯双方角色分别配置为 “蓝牙主机”和“蓝牙从机”&#xff0c;通常情况下从机以固定间隔发送“广播”数据包&#xff0c;广播包中可包含物理地址、功率、用户信息等&#xff0c;主机发现广播设…

【渝粤教育】国家开放大学2018年春季 8634-21TAndroid智能手机编程 参考试题

编号&#xff1a;8634 17-18学年第1学期期末考试 Android智能手机编程 试题&#xff08;开卷&#xff09; 一、选择题&#xff1a;&#xff08;每题4分&#xff0c;共40分&#xff09; 1&#xff0e;Android智能手机平台是基于&#xff08; &#xff09;操作系统内核开发而来…

akka2.5_发布Akka Toolkit 2.3

akka2.5最近宣布了Akka工具包 2.3.0版本的发布。 Akka是一个非常有用的工具包和运行时&#xff0c;用于在JVM上构建高度并发&#xff0c;分布式和容错的事件驱动的应用程序。 它是分布式的&#xff0c;并提供了Actor&#xff0c;Future和STM等高级抽象。 它的新版本在2.2.0发布…

2021-01-26

视频观看地址&#xff1a;https://cloud.video.taobao.com//play/u/56612045/p/1/e/6/t/1/292995127249.mp4 有线蓝牙音箱改装成无线音箱的方法&#xff1a; 1、首先拆下有线音箱功放板&#xff0c;分析功放电路 2、使用万用表&#xff0c;找到合适于蓝牙模块的电源以及音频输…

CAN光纤转换器,光纤转can模块使用说明

CAN光纤转换器&#xff0c;是集成1路标准光纤接口&#xff08;单模、多模&#xff0c; SC、 ST 可选&#xff09;、 2 路标准 CAN 总线接口的工业级 CAN 总线转光纤转换器。CAN光纤转换器可以将 CAN 总线数据转换成光信号通过光纤来传输&#xff0c;接下来杭州飞畅科技的小编就…

关于蓝牙服务UUID自定义简介

目前市面流行的在BLE应用中&#xff0c;UUID“Universally Unique Identifier”用于标识蓝牙服务以及通讯特征访问属性&#xff0c;不同的蓝牙服务和属性使用不同的访问方法&#xff0c;就像人们语言交流一样&#xff0c;语言相同才能正常交流。 蓝牙技术联盟SIG定义UUID共用了…

Java中的延迟分配

程序员本来就是懒惰的&#xff0c;而similis simili gaudet就像程序是懒惰的一样。 您听说过延迟加载吗&#xff1f; 还是懒惰的单身人士&#xff1f; &#xff08;不过&#xff0c;我个人更喜欢单一麦芽版本。&#xff09;如果使用Scala或Kotlin&#xff08;这也是一种JVM语言…

NB-IoT在智能锁领域的应用

随着近几年智能家居行业的火爆&#xff0c;智能锁在生活中出现的频率也越来越高&#xff0c;目前智能锁使用非机械钥匙作为用户识别ID的技术&#xff0c;主流技术有&#xff0c;感应卡&#xff0c;指纹识别&#xff0c;密码识别&#xff0c;面部识别等&#xff0c;极大的提高了…

飞畅 Profibus总线光纤中继器产品介绍

Profibus现场总线光纤中继器&#xff0c;符合Profibus协议&#xff0c;提供拨码开关自由选择Profibus的10种常用速率或速率自适应&#xff0c;单/双光口链网支持。Profibus光纤中继器提供1~2个独立总线电接口和1~2个光纤接口灵活搭配方式&#xff0c;可根据项目实际需求灵活配置…

modbus RTU协议设备使用无线代替有线注意事项

1.设备有线连接 Modbus是由Modicon&#xff08;现为施耐德电气公司的一个品牌&#xff09;在1979年发明的&#xff0c;是全球第一个真正用于工业现场的总线协议。ModBus网络是一个工业通信系统&#xff0c;由带智能终端的可编程序控制器和计算机通过公用线路或局部专用线路连接…

AX5243与AX5043方案对比及应用设计

一、 无线组网 成都亿佰特电子科技有限公司是一家致力于自主研发和客户定制需求的创新型公司&#xff0c;基于AX5243、AX5043芯片方案推出的窄带传输产品&#xff0c;针对不同的客户需求和通信距离选择&#xff0c;开发出了一系列包括不同封装、不同频段、不同接口形式和不同…