为什么重写HashCode和Equals
HashCode和Equals
在最开始提出一个问题:
为什么hashcode()和equals()方法要一起重写?
为什么我们要重写HashCode和Equals?
在我们业务系统中判断对象有时需要的不是严格意思上的相等,而是业务上的相等。在这种情况下,原生的equals方法就不能满足我们的需求了。
equals 源码
public boolean equals(Object obj) {return (this == obj);}
用以判断变量参数和当前实例是否相等,jdk默认实现是基于对象内存地址是否相等,如果两个对象内存地址相同, 则表示两个对象相等。
hashcode 源码
public native int hashCode();
默认情况下,该方法返回一个整数,对于每一个对象来说该数字是唯一的,但是该数字并非恒定的。
下面进行说明
/*** @ClassName Student* @Version 1.0* @Author jet5devil* @Date 2020/8/29 4:25* @Description hashcode and equals*/
public class Student {int id;String name;public Student(int id, String name) {this.id = id;this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}public static void main(String[] args) {Student s1 = new Student(1, "jet5devil");Student s2 = new Student(1, "jet5devil");System.out.println("s1.hashcode:"+s1.hashCode());System.out.println("s2.hashcode:"+s2.hashCode());System.out.println("s1.equals(s2):"+s1.equals(s2));}
}
运行结果:在没有重写任何一个方法的时候,s1 和 s2 是两个不同的对象,自然hashcode不同,且equals的结果为false
s1.hashcode:1735600054
s2.hashcode:21685669
s1.equals(s2):false
重写equals() 不重写hashcode()
@Overridepublic boolean equals(Object o) {if (o == null) {return false;}if (!(o instanceof Student)) {return false;}if (o == this) {return true;}return this.getId() == ((Student) o).getId();}
s1.hashcode:1735600054
s2.hashcode:21685669
s1.equals(s2):true
ArrayList 中的equals()?
public static void main(String[] args) {Student s1 = new Student(1, "jet5devil");Student s2 = new Student(1, "jet5devil");System.out.println("s1.hashcode:"+s1.hashCode());System.out.println("s2.hashcode:"+s2.hashCode());System.out.println("s1.equals(s2):"+s1.equals(s2));List<Student> stuList = new ArrayList<>();stuList.add(s1);System.out.println("stuList.size():"+stuList.size());System.out.println("Contains ?:"+stuList.contains(s2));}
s1.hashcode:1735600054
s2.hashcode:21685669
s1.equals(s2):true
stuList.size():1
Contains ?true
可以看出虽然hashcode 不同,但是得到了我们期望的结果
// 测试HashSet中的equals()Set<Student> stuSet = new HashSet<>();stuSet.add(s1);stuSet.add(s2);System.out.println("stuSet.size():"+stuSet.size());System.out.println("Contains?:"+stuSet.contains(new Student(1, "jet5devil")));
stuSet.size():2
Contains?:false
从结果可以看出这个时候,JVM认为不是同一个对象,虽然我们重写了equals方法
涉及HashSet的内部结构,
重写hashcode的重要性
@Overridepublic int hashCode() {return Objects.hash(id, name);}
结论
- 如果两个对象相同,则他们的hashcode一定相同
- 如果两个对象的hashcode值相同,并不意味着他们是相同的
- 对于使用Hash散列方式存储对象的数据结构:HashSet、HashMap、HashTable等,仅仅重载equals方法会导致实际业务逻辑失败
- 在比较两个对象时,仅重载hashcode方法并不能强制java忽略内存地址。
2018开年第一篇:equals()与hashCode()
java为什么要重写hashCode和equals方法
为什么重写HashCode和Equals相关推荐
- 为什么使用HashMap需要重写hashcode和equals方法_为什么要重写 hashcode 和 equals 方法?...
1. 通过Hash算法来了解HashMap对象的高效性 2. 为什么要重写equals和hashCode方法 3. 对面试问题的说明 <Java 2019 超神之路> <Dubbo ...
- HashMap存自定义对象为什么要重写 hashcode 和 equals 方法?
HashMap的k放过自定义对象么? 当我们把自定义对象存入HashMap中时,如果不重写hashcode和equals这两个方法,会得不到预期的结果. class Key{private Integ ...
- 为什么要重写 hashcode 和 equals 方法?
我在面试Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分,有 ...
- 为什么使用HashMap需要重写hashcode和equals方法_为什么要重写hashcode和equals方法?你能说清楚了吗...
我在面试Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分,有 ...
- HashMap存储自定义类型键值: 重写HashCode和equals方法
一个团体作为一个HashMap的key值,若团体成员的姓名年龄相同,则看作key值相同 因为是自定义类,所以需要重写HashCode和equals方法 public class RedVelvet { ...
- Java基础系列:重写hashCode和equals
1 场景 Map的key设置为对象时,必须重写对象的hashCode和equals方法. 原因 通过对象取值时,及时相同的对象(初始化值相同),get时,会出现null值. 方案 重写对象的hashC ...
- 为什么使用HashMap需要重写hashcode和equals方法_java常见面试题敲黑板了,HashMap最全的整理,大厂必考...
最近几天,在这样的大环境下显得疲惫不堪,但是我还是写下了这篇文章,希望对任何人都有用. HashMap是我们经常用到的数据结构,由数组和链表组成的数据结构如下图所示 上方是一张数组图片,数组里面每个地 ...
- 为什么要重写hashcode( )和equals( )?
打个比方,一个名叫张三的人去住酒店,在前台登记完名字就去了99层100号房间,此时警察来前台找叫张三的这个人住在哪间房,经过查询,该酒店住宿的有50个叫张三的,需要遍历查询,查询起来很不方便. 那么就 ...
- 详解集合之HashMap——HashMap内部结构,自动扩容机制,为什么需要重写hashcode和equals方法
HashMap底层实现是一个键值对Node数组,而Node实现了键值对Map.Entry接口 HashMap类继承结构图 1. HashMap对象的创建 1.1 默认的构造方法--只指定自动扩容时的加 ...
最新文章
- 计算开机时间c语言编程,计算电脑开机时间的代码
- transformers理论解释
- C#连接oracle的方式以及问题解决.
- boost::hana::unique用法的测试程序
- ffplay的快捷键以及选项
- 监控——《微服务设计》读书笔记
- em模型补缺失值_基于EM算法数据单变量缺失处理方法研究
- python整数序列求和_Python从菜鸟到高手(14):序列的加法和乘法
- MySQL(9)主从复制和读写分离
- Php公钥加密data是空,php 生成加密公钥加密私钥实例详解
- 剑指OFFER之数组中出现次数超过一半的数字(九度OJ1370)
- 华人微型计算机之父,计算机之父是谁?
- 计算机原理电梯控制系统设计,基于PLC电梯控制系统的设计
- UML建模工具2021年8-11月更新(共15款)
- ffmpeg gl-transitions 图片合成视频 转场特效
- python之 ffmpeg合并ts视频为mp4视频
- Java API String
- 自己构建iSCSI磁盘阵列
- 阿里入股新浪微博:动机与前景分析
- 细心的观察,耐心的倾听