JAVA学习-hashCode() 和 equals() 的作用和在集合类中的使用建议

hash

了解 hashCode() 之前最好先了解一下 hash

Java中实现hash算法icon-default.png?t=LBL2https://www.cnblogs.com/wangjiong/p/11220583.html

hashCode() 和 equals()

hashCode() 和 equals() 的作用都是用来比较两个对象是否相等,hashCode() 是通过将对象的内部地址(物理地址)转换成一个整数,然后将这个整数通过hash函数的算法返回一个 hashcode,再比较时通过比较 hashCode 来判断对象是否相等,因此在效率上,hashCode() 的效率是大于 equals() 的,但是 hashCode() 可能会发生 hash冲突,导致有时候值不同,而 hashCode 是相同的,因此在准确度上,equals() 的准确度大于 hashCode()。由此,我们可以得出两条结论:

  1. 如果两个对象通过 equals() 判读出相等,那么这两个对象的 hashCode 一定也相等。

  2. 如果两个对象的 hashCode 相等,这两个对象不一定相等。

由这两个结论,可以得出推论:如果两个对象的 hashCode 不相等,那么这两个对象一定不相等。因此在实际运用中,我们可以先用 hashCode() 去进行对比,如果 hashCode 不等,则两个对象不相等,如果 hashCode 相等,我们再调用 equals() 进行深度对比。这样既能保证效率,又能保证精准。

在集合类中的使用建议

Java 的集合类分为 List,Set,Map 三种,List 集合是有序集合,允许存在相同项;Set 集合是无序集合,不允许重复;Map 集合是键值对,键不允许重复,但是值可以允许重复。对于 Set 集合和 Map 的键这种不允许重复的,我们必须要重写 hashCode() 和 equals() 方法

举例,看以下代码:

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class Demo {
	public static void main(String[] args) {
		User user1 = new User(1, "yin", "123123");
		User user2 = new User(1, "yin", "123123");
		
		Set set=new HashSet();
		set.add(user1);
		set.add(user2);
		
		Map<User, Integer> map = new HashMap<>();
		map.put(user1, 1);
		map.put(user2, 1);
		
		//判断 user1 的内容是否和 user2 的相等
		System.out.println(user1.equals(user2));
		//user1的 hashCode
		System.out.println(user1.hashCode());
		//user2的 hashCode
		System.out.println(user2.hashCode());
		//Set集合的元素个数
		System.out.println(set.size());
		//Map集合的元素个数
		System.out.println(map.size());
	}
}

该代码返回的结果是:

false
366712642
1829164700
2
2

不难看出,虽然两个 User 对象元素的值相等,但是两个 User 对象却不相等。因此,若想要俩个相等,就得重写 hashCode() 和 equals() 方法。

//用户类
public class User {
	
	//用户id
	private int user_id;
	//用户昵称
	private String user_name;
	//用户密码
	private String password;

	public User(int user_id, String user_name, String password) {
		super();
		this.user_id = user_id;
		this.user_name = user_name;
		this.password = password;
	}

	@Override
	public boolean equals(Object obj) {
		//与类本身相同
		if(obj == this) {
			return true;
		}
		//强制转换
		User user = (User) obj;
		//判断元素是否相等
		if(user_id == user.user_id && user_name.equals(user.user_name) && password.equals(user.password)) {
			return true;
		}
		return false;
	}

	@Override
	public int hashCode() {
		//按自己的方式生成一个 hashCode
		return user_id + user_name.hashCode() * password.hashCode();
	}	
}

运行结果:

true
-138521983
-138521983
1
1

参考:equals()和hashCode()方法在集合类set中的使用 - 锟斤拷锟斤拷 - 博客园 (cnblogs.com) 

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

什巳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值