解析java中的equals方法
1 含义
在java.lang.Object下的一个访问权限为public 返回值为boolean的方法
若子类无重写,默认比较的就是两个对象(引用)的内存地址值是否相等,相等就返回true,不相等就返回false
2 作用
一般都重写Object类中的equals方法用于信息(需要展示的)的比较
当两个对象里面的内容相同时,就认为这两个对象是相等,与其地址值无关
举例说明:如比较两本书,只需要比较书的书名、类型、作者、价格、ISBN号,当所有的属性都相等时,我们就可以认为它是同一本书,和这个书的引用是否相等是没有半毛钱关系的
3 如何用
3.1 手动书写
3.1.1 书写思路
前提
两个思路都会执行下面的判断
a 当两个对象的引用指向的是同一个地址时,返回的是true;
b 当传进来的引用为null时,返回false
c 当传进来的引用和调用者不是同一个类的实例化对象时,那么返回false
(因为向下转型,要求类型必须保持一致,而且类型不一致也没有比较的必要)
思路一 把不相等的内容在前面返回false,到最后的时候才返回true
核心
依次拿属性进行比较
引用数据类型比较时
当传进来的引用中的引用数据类型的属性为null时,且调用者对应的字符串属性不为null时,那么返回false,否则,调用equals方法比较,若结果为false,则也返回false
注意:这个引用数据类型必须重写equals方法,不然默认调用的就是Object里面的方法
Object里面的equals方法比较的是两个引用的内存地址是否相等
基本数据类型比较时
若传进来的引用的基本数据类型的变量与调用者相应的基本数据类型的变量的值不相等时,则返回false
比较完最后一个属性后,依然没有返回false
执行到最后,那就返回true
思路二 直接return返回两个对象所有属性比较的结果(Objects工具类)
核心
一次性比较完所有内容,然后把比较的结果作为返回值,返回回去
比较过程
return 比较语句(用**&&符号**连接起来)
当比较引用数据类型的属性时,使用Objects.equals(引用1,引用2)进行比较,当比较基本数据类型时,直接用==比较即可,
在这个比较语句当中只要有一个为false,那么最终的返回值结果因为false,否则返回true
因为&&符号是短路与,只要有一个为false,后面的都不会进行比较了
3.1.2 示例核心代码
思路一
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Dog other = (Dog) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
思路二
@Override
public boolean equals(Object o) {
//如果条件判断里面的内容只有一行,则可以省略{}不写,但是写代码时不建议这么干
//因为这样的话逻辑很有可能把自己给绕晕的
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Dog dog = (Dog) o;
return age == dog.age && Objects.equals(name, dog.name) && Objects.equals(type, dog.type);
}
3.1.3 示例代码运行截图
3.2 编译器自动生成
3.2.1 idea篇
生成过程
a 按下Alt+Insert键
b 选择equals()和hashCode()方法
c 选择需要比较的属性,然后一直next下去(直到没有next按钮)
d 点击finish按钮
示例代码
Dog类
package Work;
import java.util.Objects;
public class Dog {
private String name;
//名字
private String type;
//类型
private int age;
//年龄
public Dog() {
}
public Dog(String name, String type, int age) {
this.name = name;
this.type = type;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
//如果条件判断里面的内容只有一行,则可以省略{}不写,但是写代码时不建议这么干
//因为这样的话逻辑很有可能把自己给绕晕的
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Dog dog = (Dog) o;
return age == dog.age && Objects.equals(name, dog.name) && Objects.equals(type, dog.type);
}
//暂时不用管hashCode方法
@Override
public int hashCode() {
return Objects.hash(name, type, age);
}
}
Test类
package Work;
public class Test {
public static void main(String[] args) {
Dog d1=new Dog("旺财","金毛",10);
Dog d2=new Dog("旺财","金毛",10);
Dog d3=new Dog("旺财","边牧",10);
System.out.println("d1与d2是同一只狗吗?"+d1.equals(d2));
System.out.println("d2与d3是同一只狗吗?"+d2.equals(d3));
}
}
示例代码运行截图
3.2.2 eclipse篇
生成过程
a 按下Alt+Shift+S快捷键
b 选择hashCode() and equals()方法
c 选择需要比较的属性
d 点击Generate按钮即可
示例代码
Dog类
public class Dog {
private String name;
// 名字
private String type;
// 类型
private int age;
// 年龄
public Dog() {
// TODO Auto-generated constructor stub
}
public Dog(String name, String type, int age) {
super();
this.name = name;
this.type = type;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//hashCode先不管,java API文档中说重写equals方法建议也一并重写了hashCode方法
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Dog other = (Dog) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
}
Test类
public class Test {
public static void main(String[] args) {
Dog d1=new Dog("旺财","金毛",10);
Dog d2=new Dog("旺财","金毛",10);
Dog d3=new Dog("旺财","边牧",10);
System.out.println("d1与d2是同一只狗吗?"+d1.equals(d2));
System.out.println("d2与d3是同一只狗吗?"+d2.equals(d3));
}
}
示例代码运行截图
3.3 应该选哪种?
3.3.1 如何选择
开发当中,一般用编译器生成。