重新对equals与hashcode的理解

之前看面试题的时候发现了一个遗忘的知识点,就是hashcode()与equals().

忽然之间弄不明白hashcode与equals分别比的是什么?谁先执行?什么情况下都执行?什么情况下都只执行一个?

为了弄懂这些我特意去网上查阅了大量的博客与文章。发现了都是讲概念不讲原理,空口套话谁不会,如果概念再加上实质的理解岂不更好?所以今天就写了这篇文章,当然内容肯定也有不妥的地方还希望网友指出,讨论,咱们共同进步一起成长。

好,不多说!我们先记住一段话“equals()==true则hashcode()==true,hashcode()==true则不一定equals()==true”

那么我们就不去object查找源码了,因为这会误导我们的思维。我们看一下我们重写之后的代码吧:

public class Users {
	private String username;
	private String password;

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((password == null) ? 0 : password.hashCode());
		result = prime * result + ((username == null) ? 0 : username.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;
		Users other = (Users) obj;
		if (password == null) {
			if (other.password != null)
				return false;
		} else if (!password.equals(other.password))
			return false;
		if (username == null) {
			if (other.username != null)
				return false;
		} else if (!username.equals(other.username))
			return false;
		return true;
	}
}

网上有人说hashcode比较的实地址,但又一老说 “equals()==true则hashcode()==true,hashcode()==true则不一定equals()==true”,当时我就十分费解,难道两个内容一样的对象要存在一个地址空间吗,这不就成了同一个对象了吗,但我们确实是new的不同的对象,当时我就不停的想啊想啊,还是想不明白,后来要不看一下源码吧,发现也没多大用处,那就自己写一个类重写这里边的方法看看他的重写过程,发现一下子解开了我的疑惑。

我们看这个hashcode究竟做了什么事

@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((password == null) ? 0 : password.hashCode());
		result = prime * result + ((username == null) ? 0 : username.hashCode());
		return result;
	}

我们发现他并没有去比较地址而是返回对象中的内容的hash值。那么我们再看看equals吧:

@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Users other = (Users) obj;
		if (password == null) {
			if (other.password != null)
				return false;
		} else if (!password.equals(other.password))
			return false;
		if (username == null) {
			if (other.username != null)
				return false;
		} else if (!username.equals(other.username))
			return false;
		return true;
	}

发现他也是对对象内容进行比较,那我们实现equals时候必须实现hashcode吗,答案是可以不实现,但建议实现为啥那么那?

我们运行流程的时候发现,当有hashcode重写实现的时候或者走object的hashcode方法的时候进行对象间比较程序总是先走hashcode然后走equals,其中equals不是必须走的而是当两个对象比较的hash值一直的时候才会走。为啥会这样那?

我们都知道机器底层其实识别的只有01代码,那么他处理hash值得速度是不是更快一些那,对系统性能也就提高一点了,而由于转换为hash值可能会重复的比如“2+4==3+3”,所以equals就是当前面的方法解决不了问题了才会登场。这也就很好的解释了前面的一句话“equals()==true则hashcode()==true,hashcode()==true则不一定equals()==true“

那么我们就知道谁先执行了?为了性能当然先执行hashcode;

什么情况下都执行?当然是hashcode自己解决不了的时候,什么时候解决不了看上边;

什么情况下只执行一个?当hashcode自己能够解决的时候;

有没有只执行equals的时候?答案是没有,就算你不去实现hashcode我们的老大object也有的,只不过返回永远是一样的所以“强制”去执行equals;

那么到底hashcode与equals分别比的是什么?

这两个只不过是解决两个对象是否想等的两个策略或者两个形式,只不过比较的方式不同,互相依赖也不依赖。

感觉我说的有问题的朋友请求骚扰。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值