Java 基础 - 如何重写equals()
ref:https://www.cnblogs.com/TinyWalker/p/4834685.html
--------------------
编写equals方法的建议:
- 显示参数命名为otherObject, 稍后转化成other变量
public boolean equals(Object otherObject)
- 检测this和otherObject是否是同一个对象的引用,是,返回true;
if(this==otherObject){
return true;
} - 检测otherObject是否为null, 是, 返回false;
if(otherObject == null){
return false;
} - 比较this和otherObject是否属于同一个类. 如果equals的语义在每个子类中有所改变,就使用getClass检测:
if(getClass() != otherObject.getClass()){
return false;
}如果子类语义相同,使用instanceof检测:
if(!(otherObject instanceof Employee)){
return false;
} - 将otherObject转化为相对应的类型变量other
Employee other = (Employee)otherObject;
- 对所需要的比较的数据域进行比较. 如果是基本数据类型,使用a==b比较; 如果是对象比较,调用Objects.equals(a, b)进行比较
return Objects.equals(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay);
整个流程可以参照例1;
例1:雇员对象比较
如果两个雇员对象的姓名, 薪水和雇佣一样,就认为它们相等.重写equals方法如下:
public class Employee {
private String name;
private double salary;
private Date hireDay;
...
@Override
public boolean equals(Object obj) {
// 如果为同一对象的不同引用,则相同
if (this == obj) {
return true;
}
// 如果传入的对象为空,则返回false
if (obj == null) {
return false;
}
// 如果两者属于不同的类型,不能相等
if (getClass() != obj.getClass()) {
return false;
}
// 类型相同, 比较内容是否相同
Employee other = (Employee) obj;
return Objects.equals(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay);
}
}
注意,比较通过Objects中静态函数equals比较两个对象是否相等.该方法源码如下:
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
这样,当两个对象都为null时,返回true,例如,两个Employee对象的name都为null, 返回true; 如果第一个对象不为null,则调用a.equals(Object obj)方法
常见equals方法实现错误
1-未使用@override对覆盖超类的方法进行标记.
public class Employee {
public boolean equals(Employee other) {
return Objects.equals(name, other.name) && salary ==other.salary && Objects.equals(hireDay, other.hireDay);
}
这个方法声明的显示参数类型是Employee. 其结果并没有覆盖Object中的equals方法,而是定义了一个完全无关的方法.为了避免发生类型错误,可以使用@override对覆盖超类的方法进行标记.
2-没有同时override hashcode()函数
object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true;
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。如下:
(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true
(2)当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2)必须为false
如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址,重写之后目的是为了比较两个对象的value值是否相等。特别指出利用equals比较八大包装对象
(如int,float等)和String类(因为该类已重写了equals和hashcode方法)对象时,默认比较的是值,在比较其它自定义对象时都是比较的引用地址
hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。
这样如果我们对一个对象重写了euqals,意思是只要对象的成员变量值都相等那么euqals就等于true,但不重写hashcode,那么我们再new一个新的对象,
当原对象.equals(新对象)等于true时,两者的hashcode却是不一样的,由此将产生了理解的不一致,如在存储散列集合时(如Set类),将会存储了两个值一样的对象,
导致混淆,因此,就也需要重写hashcode()
举例说明:
public override bool Equals(object obj)
{
if (!(obj is BalanceSheetReport expect))
return false;
return this.EndSum == expect.EndSum
&& this.PreSum == expect.PreSum
&& this.SequenceId == expect.SequenceId
&& this.ProjectId == expect.ProjectId;
}
public override int GetHashCode()
{
return this.PreSum.GetHashCode()
^ this.EndSum.GetHashCode()
^ this.SequenceId.GetHashCode()
^ this.ProjectId.GetHashCode();
}
Java 基础 - 如何重写equals()的更多相关文章
- 【Java基础】重写equals需要重写hashcode
Object里的equals用来比较两个对象的相等性,一般情况下,当重写这个方法时,通常有必要也重写hashcode,以维护hashcode方法的常规协定,或者说这是JDK的规范,该协定声明相等对象必 ...
- java构造方法和重写equals
Cell的构造函数 package Test; import java.util.Objects; public class Cell { int a; int b; public int getA( ...
- [转]java基础学习总结——equals方法
一.equals方法介绍 1.1.通过下面的例子掌握equals的用法 1 package cn.galc.test; 2 3 public class TestEquals { 4 public s ...
- java基础学习总结——equals方法
一.equals方法介绍 1.1.通过下面的例子掌握equals的用法 package cn.galc.test; public class TestEquals { public static vo ...
- 【java基础】 == 和 equals() 的区别
==号和equals()方法都是比较是否相等的方法,那它们有什么区别和联系呢? 首先,==号在比较基本数据类型(指的值类型)时比较的是值,而用==号比较两个对象时比较的是两个对象的地址值: int x ...
- java中为什么重写equals时必须重写hashCode方法?
在上一篇博文Java中equals和==的区别中介绍了Object类的equals方法,并且也介绍了我们可在重写equals方法,本章我们来说一下为什么重写equals方法的时候也要重写hashCod ...
- java removeAll和重写equals、hashcode引起的性能问题
问题背景: 上周发现了一个spark job的执行时间从原来的10-15分钟延迟到了7个小时!wtf,这是出了什么事引起了这么大的性能问题!! 立马查看job的运行日志,发现多次运行都是在某一个固定的 ...
- 【原创】关于java对象需要重写equals方法,hashcode方法,toString方法 ,compareto()方法的说明
在项目开发中,我们都有这样的经历,就是在新增表时,会相应的增加java类,在java类中都存在常见的几个方法,包括:equals(),hashcode(),toString() ,compareto( ...
- java 中为什么重写 equals 后需要重写 hashCode
本文为博主原创,未经允许不得转载: 1. equals 和 hashCode 方法之间的关系 这两个方法都是 Object 的方法,意味着 若一个对象在没有重写 这两个方法时,都会默认采用 Objec ...
随机推荐
- js面向对象(一)---基本的概念、属性、方法
一.什么是面向对象编程 1.用对象的思想去写代码,就是面向对象编程 2.我们一直在使用对象,如数组Array 时间Date //我们把系统自带的对象,叫做系统对象 var arr = new A ...
- 【POJ】1287 Networking
题目链接:http://poj.org/problem?id=1287 题意:n个点,m条网线长度.求构成网络的最小网线长度. 题解:最小生成树裸题.套板子. 代码: #include<iost ...
- js drag drop 收藏夹拖拽移除的简单例子
代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title& ...
- mysql数据库 --数据类型、约束条件
今日内容 表的详细使用 1.创建表的完成语法 2.字段类型 整型.浮点型.字符类型.日期类型.枚举与集合类型 3.约束条件 primary key.unique.not null.default 一. ...
- webpack 配置es6 语法
使用babel来编译es6的语法; 1.在终端上输入指令 npm install webpack babel-loader babel-core babel-preset-es2015 --save- ...
- Spring Boot学习笔记一
Spring Boot简介 前言:本章简单介绍Spring boot的使用. (第二天springboot的学习之路:https://www.cnblogs.com/LBJLAKERS/p/12003 ...
- HIVE常用SQL语句及语法
HIVE建内部表语句 create table dll102.sougou (id string,pwd string,name string,count int,seqno int,address ...
- Json数据交换一Gson
Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库.可以将一个 JSON 字符串转成一个 Java 对象,或者反过来. 添加依赖 <depe ...
- flyway 管理数据库版本
Flyway 和 Liquibase 都是 Java 项目中常用的 DB migration 工具, 从使用简便性看,Flyway 比 Liquibase 更简单, 从 github 的 star 数 ...
- thinkphp 快速缓存
如果你的存储数据没有有效期的需求,那么系统还提供了一个快速缓存方法F可以用来更快的操作. 大理石平台厂家 F方法可以支持不同的存储类型,如果是文件类型的话,默认保存在DATA_PATH目录下面. 快速 ...