重写equals 和hashCode 探解之洗洗脚(一)

以前一直只听某些所谓的高人经常说什么“那就重写equals方法嘛”或者“XXX 条件下,要重写equals方法”啊什么的论语。但自己从来没有看见过,理解过其中的究竟。也从来没有写过。更不知道在什么时候可以用,以及怎么用。原来发现人参泡在“自己不知道自己不明白”的杯具中。

现归结以前一直不明白的问题如下:

Q1:为什么要重写equals和HashCode?
Q2:如果重写了上述2个方法,那么究竟是修改了哪个对象的equals和hashCode方法?
Q3:equals方法中的return int 和hashCode方法中的 return boolean 这2个返回值到底是什么意思? 有什么意义? 如果返回值不同会导致什么样的结果?
Q4:equals方法和hashCode方法调用的顺序是怎样的? 以及2个方法被调用的时机? 2个方法会不会有可能不被调用?或者必须2者中的某一个是不是一定会被调用? 等等

通过老大的指点,现通过一个简单案例和图片来回答以上4个问题:

测试案例情形:
将对象 User 放到集合SET里去,然后打印SET集合的对象的数量是多少。

Part 1 代码:


public class User{
public String userName;
public String password;

public User(String userName,String password){
this.userName = userName;
this.password = password;
}

public static void main(String[] arg){
Set<User> users = new HashSet<User>(); //L1
User user=new User("lisa","ddd"); //L2
users.add(user); //L3
// User user1=new User("lisa","ddd"); //L4
// users.add(user1); //L5
System.out.println(“size---->"+users.size()); //L6
}

//重写hashCode和equals方法
public int hashCode(){

system.out.println("fn ----> hashCode");
return 1;
}

public boolean equals(){
system.out.println("fn ----> equals");
return true;
}

}


执行结果:
fn ----> hashCode
size---->1



分析:
L1:首先在内存块堆中给users划分一块空间地址比如a1,再栈中给对象new HashSet划分一块空间比如地址a2。a1指向a2。
L2:同理user--->b1 ;new User("lisa","ddd")---->b2; b1---->b2.
L3: 将user加入到 users中。即将b1 加入到a2中。
在加入的过程中,即调用 hashcode()方法将对象user灌到users中去,而这里的return 1.即理解为set为一栋大楼,而1则为大楼中的第一个房间,而这里即是把user对象放到大楼里面的第一个房间里面去存起。

于是打印了“fn ----> hashCode”。
接着打印 size---->1

但这里为什么只打印了fn ----> hashCode 和 size---->1,而没有打印fn ----> equals 呢?

那就要从hashSet的理解开始了:

首先大家知道hashSet默认是不能放重复的对象到它里面去,hashCode就是负责将对象怎样放在set里面去,而equals()方法就是负责判断你前后放进的对象是否是“重复”的。

那所谓的“重复”又是什么意思呢? 重复就是根据你的业务来判断了。

打个比方:
(1)公安机关认为只要某人的身份证号是一样的,那就是同一个人,不管你是男是女还是李宇春,或者长得美丑或像宋祖德。只要身份证是同一个号码,我公安机关就认定你是同一个人。

(2)但对于普通老百姓就不这样认为了,我不仅要你身份证号码是一样的,还要求你那张脸一定要是李宇春那张脸的,我才认为是同一个人,至少春迷是这样认为的。

所以重复就是不同的业务来定义,对不对。那么就要用到equals 方法来作为人们的判断条件了。因此如果我们要根据不同的业务来判断一个对象是不是同一个对象,就需要我们重写该对象的hashCode和 equals 方法了。对不对。我们这里是判断User对象,因此就重写了User对象的hashCode和 equals 方法.因此这里就回答了Q1和Q2 了。


继续 初始时SET里面为空,因此程序就只负责将user灌到users中,而不用去比较了,因为没有比较的对象啊。所以就没有调用 equals 方法了,因此就没有打印 fn----->equals 了。


感谢--徐老师

继续见 重写equals 和hashCode 探解之洗洗脚(二)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值