equals()在哪里

首先我们知道Java中Object类是所有类的父类,它里面定义了equals()方法:

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

可以看到是使用= =来进行比较的,那么= =是什么意思呢?其实是比较两个对象的的内存地址。(这里顺便提一下,可以去了解一下Java的堆栈。)
=》若object1.equals(object2)为true,则表示equals1和equals2实际上是引用同一个对象。

Java中重写的equals()

这里我们看一下java的一些自带的包装类怎么重写equals()的:

  • String.java
    public boolean equals(Object anObject) {if (this == anObject) {return true;}if (anObject instanceof String) {String anotherString = (String)anObject;int n = value.length;if (n == anotherString.value.length) {char v1[] = value;char v2[] = anotherString.value;int i = 0;while (n-- != 0) {if (v1[i] != v2[i])return false;i++;}return true;}}return false;}

我们可以非常清晰的看到String的equals()方法是进行内容比较,而不是单纯的引用比较

  • Integer.java
    public boolean equals(Object obj) {if (obj instanceof Integer) {return value == ((Integer)obj).intValue();}return false;}

其他的就不一一举例了。

在Java中比较的推荐方法

所以我们一般比较基本数据类型的时候,使用"==",例如 int i = 0; if (i == 1){…},比较两个Integer包装类类型的时候就可以使用equals(),因为Java已经重写了equals()方法了。另外给出几点建议,在java中进行比较,我们需要根据比较的类型来选择合适的比较方式:

  1. 对象域,使用equals方法 。
  2. 类型安全的枚举,使用equals或== 。
  3. 可能为null的对象域 : 使用==null 和 equals 。
  4. 数组域 : 使用 Arrays.equals 。
  5. 除float和double外的原始数据类型(int,byte等) : 使用 == 。
  6. float类型: 使用Float.foatToIntBits转换成int类型,然后使用==。
  7. double类型: 使用Double.doubleToLongBit转换成long类型,然后使用==。
    其中6,7参考java中的对应的包装类实现:
public boolean equals(Object obj) {return (obj instanceof Float)&& (floatToIntBits(((Float)obj).value) == floatToIntBits(value));}
}

为什么要在我们自己的类中重写equals()

但是有时候我们不满足于使用基本数据类型和Java实现的一些继承自Object的哪些类,比如我们实现一个Person类,它是继承自Object类的,所以它的equals()方法默认使用的是文章开头提到的哪个equals()方法,当我们使用equals()进行比较的时候,比较内存地址,那么有可能出现两个Person对象的参数都相同(比如年龄,身份证号等,在我们的实际认知中认为这两个人就是一个人,应该返回true),但是由于他们的内存地址是不一样的,所以equals()方法会返回false。
那么我们就需要去重写equals()方法。

重写equals()的规范

需要注意的是,在Java规范中,它对equals()方法的使用必须要遵循如下几个规则:

  1. 自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
  2. 对称性:对于任何非空引用值 x 和 y,当且仅当y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
  3. 传递性:对于任何非空引用值 x、y 和z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
  4. 一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回4、一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回false,前提是对象上 equals 比较中所用的信息没有被修改
  5. 对于任何非空引用值 x,x.equals(null) 都应返回false。

重写equals()可能的误区

查看下述代码:


public class TestEquals {public static void main(String[] args) {Employee employee = new Employee("mily",1);Employee employee2 = new Employee("mily",2);Person p1 = new Person("mily");System.out.println(p1.equals(employee));System.out.println(p1.equals(employee2));System.out.println(employee.equals(employee2));}
}class Person {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public Person(String name) {this.name = name;}@Overridepublic boolean equals(Object obj) {if (obj instanceof Person) {Person person = (Person) obj;if (person.getName() == null | name == null) {return false;} else {return name.equalsIgnoreCase(person.getName());}}return false;}
}class Employee extends Person {private int id;public int getId() {return id;}public void setId(int id) {this.id = id;}public Employee(String name, int id) {super(name);this.id = id;}@Overridepublic boolean equals(Object obj) {if (obj instanceof Employee) {Employee employee = (Employee) obj;return super.equals(obj) && employee.getId() == id;}return false;}
}

输出:
true
true
false

上述代码中,我定义了一个Person类,有一个属性name;还定义了一个Employee类,它是Person的子类,多出一个id的属性;在测试代码中“new”出了三个对象:

  1. name为mily,id为1的一个职员 —— employee
  2. name为mily,id为2的职员 —— employee2
  3. name为mily的一个普通人 —— p1
    在大家的认知下,应该是三者都不是“equal”的,但是在执行 p1.equals(employee)时返回的是true,仔细看了代码之后你就会发现问题所在,代码把employee当成一个Person对象去执行equals方法了,比较了name发现一样,就认为是“equal”了,这是一种很常见的误区。

一般的equals()写法

下面给出一个完美的 equals 方法的建议:

1、显示参数命名为 otherObject,稍后会将它转换成另一个叫做 other 的变量。

2、判断比较的两个对象引用是否相等,如果引用相等那么表示是同一个对象,那么当然相等

3、如果 otherObject 为 null,直接返回false,表示不相等

4、比较 this 和 otherObject 是否是同一个类:如果 equals 的语义在每个子类中有所改变,就使用 getClass 检测;如果所有的子类都有统一的定义,那么使用 instanceof 检测

5、将 otherObject 转换成对应的类类型变量

6、最后对对象的属性进行比较。使用 == 比较基本类型,使用 equals 比较对象。如果都相等则返回true,否则返回false。注意如果是在子类中定义equals,则要包含 super.equals(other)

按照上述的equals()规范,我的实现如下:

public class TestEquals2 {public static void main(String[] args) {Employee employee = new Employee("mily",1);Employee employee2 = new Employee("mily",1);Person p1 = new Person("mily");System.out.println(p1.equals(employee));System.out.println(p1.equals(employee2));System.out.println(employee.equals(employee2));Employee employee3 = new Employee(null,1);Employee employee4 = new Employee(null,1);Person p2 = new Person(null);System.out.println(p2.equals(employee3));System.out.println(p2.equals(employee4));System.out.println(employee3.equals(employee4));}
}class Person {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public Person(String name) {this.name = name;}@Overridepublic boolean equals(Object obj) {if(this == obj){return true;}if(obj == null || getClass() != obj.getClass()){return false;}Person person = (Person) obj;if(person.getName() == null | name == null) {return false;} else {return name.equalsIgnoreCase(person.getName());}}
}class Employee extends Person {private int id;public int getId() {return id;}public void setId(int id) {this.id = id;}public Employee(String name, int id) {super(name);this.id = id;}@Overridepublic boolean equals(Object obj) {if(this == obj){return true;}if(obj == null || getClass() != obj.getClass()){return false;}Employee employee = (Employee) obj;if(employee.getName() == null | getName() == null) {return false;}else {return getName().equalsIgnoreCase(employee.getName()) && employee.getId() == id;}}
}

结果:
false
false
true
false
false
false

不足之处,望指正!

Java中的equals()方法相关推荐

  1. Java中重写equals()方法时注意点

    Java中重写equals()方法时注意点 一直说,重写一个对象的equals()方法时我们必须重写HashCode()方法,但是如果我们不重写呢?会有什么影响呢? 首先看一下,什么情况下我们需要重写 ...

  2. java中equals函数所在的类,重写Java中的equals方法介绍

    Java中,只有8种基本类型不是对象,例如:4种整形类型(byte, short, int,long),2种浮点类型(flout, double),boolean, char不是对象,其他的所有类型, ...

  3. JAVA中“==”与equals()方法区别

    equals 方法是 java.lang.Object 类的方法 有两种用法说明: (1)对于字符串变量来说,使用"=="和"equals()"方法比较字符串时 ...

  4. java中的equals方法+hashCode方法

    [0]README 0.1)以下内容均为原创,包括源代码, 旨在理清 equals 和 hashCode 方法的 实现原理: 0.2) for full resource code, please v ...

  5. JAVA中重写equals()方法的同时要重写hashcode()方法

    object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true:注意:当此方法 ...

  6. 在聊Java中的equals方法

    2019独角兽企业重金招聘Python工程师标准>>> java规范中equals方法特征 自反性(对于任何非空引用x, x.equals(x) 返回true;) 对称性(对于任何引 ...

  7. Java 中 == 和equals()方法的不同点

    在Java中,基本变量(int a=5)存储在栈中,引用型变量存储在栈和堆中,在栈中存储变量的地址,在堆中存储变量的值. ==,对于基本变量比较的是变量的值,对于引用变量比较的是变量的地址,是地址的比 ...

  8. java中的equals方法

    一.equals方法介绍 1.1.通过下面的例子掌握equals的用法 1 package cn.galc.test;2 3 public class TestEquals {4 public sta ...

  9. Java中的equals()方法重写

    public boolean equals(Object obj) {return (this == obj); } Object类提供的 equals() 方法默认是用 == 来进行比较的,也就是说 ...

最新文章

  1. R语言画形状—直线、矩形、多边形等
  2. root cause of error messagw for a mixed usage of 01 and 03
  3. centos6.5 rpm安装mysql_CentOS6.5系统下RPM包安装MySQL5.6(转)
  4. 基于链路思想的SpringBoot单元测试快速写法
  5. Linux系统上Crontab定时执行教程
  6. 欧洲与北美5G开战,最后的赢家却是高通?
  7. docker harbor 域名_docker 安装Harbor
  8. 在 Ubuntu 上配置高性能的 HHVM 环境
  9. kong自定义插件(修改官方插件)
  10. 小白白红队初成长(5)win权限维持
  11. Hspice学习资源和心得
  12. .net的快递单号自动识别查询api接口demo代码实例(快递鸟案例)
  13. 单位换算:潜热通量(w/m2)转换为蒸散发(mm/s)
  14. Golang调用mssql存储过程
  15. 偏差代替误差进行稳态分析
  16. win10浏览器闪退_win10系统打开360浏览器就闪退是什么情况?
  17. python 做网站 知乎_python做网站 知乎的搜索结果-阿里云开发者社区
  18. 一个不成熟的模板引擎思路
  19. win10 增加eng语言
  20. 2022年G1工业锅炉司炉特种作业证考试题库及在线模拟考试

热门文章

  1. 一个模仿水滴筹的项目(只是一个半成品)
  2. 关于《火影忍者 博人传》的一点想法
  3. 如何做二维码?教你一招轻松制作个性二维码
  4. 假如有人把支付宝存储服务器炸了,里面的钱是不是就都没有了?
  5. 你理解常见如阿里,和友商大数据平台的技术体系差异以及发展趋势和技术瓶颈,在存储和计算两个方面进行概述
  6. linux下如何配置svn,Linux下SVN安装与配置详解
  7. STOS指令和LEA指令
  8. jQuery是什么及jQuery写法
  9. IPMP、PMP、CPMP三个证书该如何选择,有什么区别,哪个对于工作上的
  10. 10-15万预算,网上购车平台这几款车型推荐,超低首付购车上私户