目录
区别
如何对equals重写
为何重写equals方法就得重写hashCode方法
扩展延伸
1、使用HashSet存储自定义类对象时为什么要重写equals和hashCode方法?
2、HashMap为什么要同时重写hashCode和equals方法
区别
一、对象类型不同
1、equals():是超类Object中的方法。
2、==:是操作符。
二、比较的对象不同
1、equals():用来检测两个对象是否相等,即两个对象的内容是否相等。
(如Float,Double,Integer,Date,Point等)和String类(因为该类已重写了equals和hashcode方法)对象时,默认比较的是值,在比较其它自定义对象时都是比较的引用地址
2、==:用于比较引用和比较基本数据类型时具有不同的功能,具体如下:
(1)、基础数据类型:比较的是他们的值是否相等,比如两个int类型的变量,比较的是变量的值是否一样。
(2)、引用数据类型:比较的是引用的地址是否相同,比如说新建了两个User对象,比较的是两个User的地址是否一样。
对于自定义的对象,如果其类中没有对equals进行重写,其equals方法与==就也是等效的,除非在此类中重写equals。
三、运行速度不同
1、equals():没有==运行速度快。
2、==:运行速度比equals()快,因为==只是比较引用。
如何对equals重写
1、自反性:对任意引用值X,x.equals(x)的返回值一定为true;
2、对称性:对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true;
3、传递性:如果x.equals(y)=true, y.equals(z)=true,则x.equals(z)=true ;
4、 一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变;
5、非空性:任何非空的引用值X,x.equals(null)的返回值一定为false 。
public class MyDate {
private int year;
private int month;
private int day;
public MyDate(int day, int month, int year){
this.day = day;
this.month = month;
this.year = year;
}
public boolean equals(Object obj){
if(this == obj){
return true;
}
if(obj instanceof MyDate){
MyDate md = (MyDate) obj;
return this.year == md.year && this.month == md.month && this.day == md.day;
}else{
return false;
}
}
}
为何重写equals方法就得重写hashCode方法
当我们将equals方法重写后有必要将hashCode方法也重写,这样做才能保证不违背hashCode方法中“相同对象必须有相同哈希值”的约定。
扩展延伸
1、使用HashSet存储自定义类对象时为什么要重写equals和hashCode方法?
HashSet类中add()、remove()、contains()方法对同一个对象的判断机制,涉及 两者。
HashSet集合对象如何判断数据元素是否重复:
- 检查待存对象hashCode值是否与集合中已有元素对象hashCode值相同,
- 如果hashCode不同则表示不重复, 如果hashCode相同再调用equals方法进一步检查
,equals返回真表示重复,否则表示不重复。
故而不重写的话, 判断的时候会有问题。
2、HashMap为什么要同时重写hashCode和equals方法
以put方法为例,判断key是否存在时, 类似 HashSet的add()过程:
hash(key) : 首先判断hashCode(key) ,相同时再判断equals(key).