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相关推荐

  1. 为什么使用HashMap需要重写hashcode和equals方法_为什么要重写 hashcode 和 equals 方法?...

    1. 通过Hash算法来了解HashMap对象的高效性 2. 为什么要重写equals和hashCode方法 3. 对面试问题的说明 <Java 2019 超神之路> <Dubbo ...

  2. HashMap存自定义对象为什么要重写 hashcode 和 equals 方法?

    HashMap的k放过自定义对象么? 当我们把自定义对象存入HashMap中时,如果不重写hashcode和equals这两个方法,会得不到预期的结果. class Key{private Integ ...

  3. 为什么要重写 hashcode 和 equals 方法?

    我在面试Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分,有 ...

  4. 为什么使用HashMap需要重写hashcode和equals方法_为什么要重写hashcode和equals方法?你能说清楚了吗...

    我在面试Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分,有 ...

  5. HashMap存储自定义类型键值: 重写HashCode和equals方法

    一个团体作为一个HashMap的key值,若团体成员的姓名年龄相同,则看作key值相同 因为是自定义类,所以需要重写HashCode和equals方法 public class RedVelvet { ...

  6. Java基础系列:重写hashCode和equals

    1 场景 Map的key设置为对象时,必须重写对象的hashCode和equals方法. 原因 通过对象取值时,及时相同的对象(初始化值相同),get时,会出现null值. 方案 重写对象的hashC ...

  7. 为什么使用HashMap需要重写hashcode和equals方法_java常见面试题敲黑板了,HashMap最全的整理,大厂必考...

    最近几天,在这样的大环境下显得疲惫不堪,但是我还是写下了这篇文章,希望对任何人都有用. HashMap是我们经常用到的数据结构,由数组和链表组成的数据结构如下图所示 上方是一张数组图片,数组里面每个地 ...

  8. 为什么要重写hashcode( )和equals( )?

    打个比方,一个名叫张三的人去住酒店,在前台登记完名字就去了99层100号房间,此时警察来前台找叫张三的这个人住在哪间房,经过查询,该酒店住宿的有50个叫张三的,需要遍历查询,查询起来很不方便. 那么就 ...

  9. 详解集合之HashMap——HashMap内部结构,自动扩容机制,为什么需要重写hashcode和equals方法

    HashMap底层实现是一个键值对Node数组,而Node实现了键值对Map.Entry接口 HashMap类继承结构图 1. HashMap对象的创建 1.1 默认的构造方法--只指定自动扩容时的加 ...

最新文章

  1. 计算开机时间c语言编程,计算电脑开机时间的代码
  2. transformers理论解释
  3. C#连接oracle的方式以及问题解决.
  4. boost::hana::unique用法的测试程序
  5. ffplay的快捷键以及选项
  6. 监控——《微服务设计》读书笔记
  7. em模型补缺失值_基于EM算法数据单变量缺失处理方法研究
  8. python整数序列求和_Python从菜鸟到高手(14):序列的加法和乘法
  9. MySQL(9)主从复制和读写分离
  10. Php公钥加密data是空,php 生成加密公钥加密私钥实例详解
  11. 剑指OFFER之数组中出现次数超过一半的数字(九度OJ1370)
  12. 华人微型计算机之父,计算机之父是谁?
  13. 计算机原理电梯控制系统设计,基于PLC电梯控制系统的设计
  14. UML建模工具2021年8-11月更新(共15款)
  15. ffmpeg gl-transitions 图片合成视频 转场特效
  16. python之 ffmpeg合并ts视频为mp4视频
  17. Java API String
  18. 自己构建iSCSI磁盘阵列
  19. 阿里入股新浪微博:动机与前景分析
  20. 细心的观察,耐心的倾听

热门文章

  1. 用matlab画干涉条纹图,matlab干涉条纹处理
  2. orgchart实现组织结构图
  3. 盘古开天辟地之源码编译安装LAMP
  4. android常用控件实验报告,ui设计实验报告.doc
  5. 智能家居前装好还是后装好?哪个才是全屋智能更好的选择?
  6. .NET Core 之 七 EF Core(四)
  7. SEO人员,该如何打造具有搜索属性的内容?
  8. 硅谷创业教父保罗·格雷厄姆给的创业建议书
  9. STF环境搭建运行及踩坑记录
  10. html怎样把字幕贴着色块走,手把手教你用HTML做音画贴