Java常用API(五)—— 重写对象的equals和hashCode方法
2021/5/9 14:26:01
本文主要是介绍Java常用API(五)—— 重写对象的equals和hashCode方法,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
未重写前,调用父类Object的equals方法,该方法比较的是引用对象存储的值:即对象在堆中的地址。
package com.JavaSe.eq; class Line{ double k, b; public Line(double kk, double bb){ this.k = kk; this.b = bb; } } public class TestEq { public static void main(String[] args) { Line line1 = new Line(1.5, 2.2); Line line2 = new Line(1.5, 2.2); System.out.println(line1.equals(line2));//false } }
只重写equals不重写hashCode
package com.JavaSe.eq; import java.util.HashSet; import java.util.Objects; import java.util.Set; class Line{ double k, b; public Line(double kk, double bb){ this.k = kk; this.b = bb; } //重写equals方法: 比较k和b是否相等 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Line line = (Line) o; return Double.compare(line.k, k) == 0 && Double.compare(line.b, b) == 0; } @Override public String toString() { return "Line{" + "k=" + k + ", b=" + b + '}'; } } public class TestEq { public static void main(String[] args) { Line line1 = new Line(1.5, 2.2); Line line2 = new Line(1.5, 2.2); System.out.println(line1.equals(line2));//重写完之后比较结果为:true Set<Line> set = new HashSet<>(); set.add(line1); set.add(line2); System.out.println(set); // [Line{k=1.5, b=2.2}, Line{k=1.5, b=2.2}] System.out.println( line1.hashCode() == line2.hashCode()); //false } }
可以发现,equals比较的结果为true,我们认定相同{k,b}为同一对象,这符合我们的要求。但是使用HashSet添加上述两个对象的时候,居然都添加进去了。这显然不符合我们的预期。这是因为hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。而上述对象没有重写hasCode方法,两个对象的hashCode值不一样,也就被认定为两个不同的对象了。
通过看 hashSet 的 add 方法能够得知 add 方法里面使用了对象的 hashCode 方法来判断,所以我们需要重写 hashCode 方法来达到我们想要的效果。
重写equals和hashCode
如何计算对象的hashCode
生成一个 int 类型的变量 result,并且初始化一个值,比如17。
对类中每一个重要字段,也就是影响对象的值的字段,也就是 equals 方法里有比较的字段,进行以下操作:
a. 计算这个字段的值 filedHashValue = filed.hashCode();
b. 执行 result = 31 * result + filedHashValue;
package com.JavaSe.eq; import java.util.HashSet; import java.util.Objects; import java.util.Set; class Line{ double k, b; public Line(double kk, double bb){ this.k = kk; this.b = bb; } //重写equals方法: 比较k和b是否相等 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Line line = (Line) o; return Double.compare(line.k, k) == 0 && Double.compare(line.b, b) == 0; } //计算HashCode @Override public int hashCode() { return Objects.hash(k, b); } @Override public String toString() { return "Line{" + "k=" + k + ", b=" + b + '}'; } } public class TestEq { public static void main(String[] args) { Line line1 = new Line(1.5, 2.2); Line line2 = new Line(1.5, 2.2); System.out.println(line1.equals(line2));//重写完之后比较结果为:true Set<Line> set = new HashSet<>(); set.add(line1); set.add(line2); System.out.println(set); //[Line{k=1.5, b=2.2}] System.out.println( line1.hashCode() == line2.hashCode()); //true } }
参照Objects.hash(k, b)的源码,hashCode计算方法也可写成如下:
@Override public int hashCode() { //使用包装类 Double kk = this.k; Double bb = this.b; int result = 1; result = 31 * result + (kk == null ? 0 : kk.hashCode()); result = 31 * result + (bb == null ? 0 : bb.hashCode()); return result; }
参考文章:
Java 如何重写对象的 equals 方法和 hashCode 方法
这篇关于Java常用API(五)—— 重写对象的equals和hashCode方法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-04TiDB 资源管控的对撞测试以及最佳实践架构
- 2024-07-03万字长文聊聊Web3的组成架构
- 2024-07-02springboot项目无法注册到nacos-icode9专业技术文章分享
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现