前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >再论:关于 equals 和 hashCode

再论:关于 equals 和 hashCode

作者头像
shengjk1
发布2020-03-17 18:01:52
3890
发布2020-03-17 18:01:52
举报
文章被收录于专栏:码字搬砖码字搬砖

上篇 关于 equals 和 hashCode 关于 equals 和 hashCode 的基本性质已经论述过了。

1.什么时候应该覆盖 equals?

我们知道 equals 默认比较的内存地址,即是否为同一个对象。如果类具有了自己特有的逻辑相等,即属性值等,的概念时,并且超类没有覆盖或者覆盖了单不满足子类需求的情况下重写 equals。

但对于类似枚举类这样的 class 而言,每个属性最多只存在一个对象,逻辑相等与内存地址相等时一样的,不需要重写。

2.为什么要覆盖 equals( hashCode) ?

代码语言:javascript
复制
/**
 * @author shengjk1
 * @date 2020/3/14
 */
public class TestEquals {
	public static void main(String[] args) {
		HashMap<Student, String> map = new HashMap<>();
		Student student = new Student(16, "小明");
		map.put(student, "a");
		Student student1 = new Student(16, "小明");
		System.out.println(map.containsKey(student1));
	}
}

class Student {
	private int age;
	private String name;
	
	public Student(int age, String name) {
		this.age = age;
		this.name = name;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	//	@Override
//	public boolean equals(Object o) {
//		if (this == o) return true;
//		if (o == null || getClass() != o.getClass()) return false;
//		Student student = (Student) o;
//		return age == student.age &&
//				Objects.equals(name, student.name);
//	}
//
	@Override
	public int hashCode() {
		return Objects.hash(age, name);
	}
}

结果

代码语言:javascript
复制
false

这完全不是我们想要的,我们希望的是 map.containsKey(student1) 为true。但为什么是 false 呢?通过源码我们可以知道 应为 equals 不等,导致的。同理,对于 hashCode 也是如此。

3.是否是任何时候都需要覆盖 equals 和hashCode?

答案是 否定的。

还记得上一篇说过的吗,JDK 内部就有违背 equals hashCode 一致性规则的。另外的话,hashCode 仅仅针对 hash 表来说才有用。

代码语言:javascript
复制
/**
 * @author shengjk1
 * @date 2020/3/14
 */
public class TestEquals {
	public static void main(String[] args) {
		HashMap<Student, String> map = new HashMap<>();
		Student student = new Student(16, "小明");
		map.put(student, "a");
		Student student1 = new Student(16, "小明");
		System.out.println("map " + map.containsKey(student1));
		
		ArrayList<Student> students = new ArrayList<>();
		students.add(student);
		System.out.println("list " + students.contains(student1));
	}
}

class Student {
	private int age;
	private String name;
	
	public Student(int age, String name) {
		this.age = age;
		this.name = name;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;
		Student student = (Student) o;
		return age == student.age &&
				Objects.equals(name, student.name);
	}
//
//	@Override
//	public int hashCode() {
//		return Objects.hash(age, name);
//	}
}

结果

代码语言:javascript
复制
map false
list true

对于 list 而言,根本就不需要 比较hashCode,我们也违背了 equals 与 hashCode 的一致性,但对于 students.contains(student1) 结果就是正确的

4.总结

1.java 集合内部比较对象是否相等一般用的都是 equals ,所以 equals 是要尽量重写的。

2.而对于 hashCode 来说,对于 hash table 来说是必须要重写的,其他的可以不重写。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-03-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档