Java中重写equals方法为什么要重写hashcode方法?

直接看下面的例子:

首先我们只重写equals()方法

  1. public class Test {
  2.  
  3. public static void main(String[] args) {
  4. User user1 = new User();
  5. User user2 = new User();
  6. System.out.println(user1.equals(user2));
  7. System.out.println(user1.hashCode());
  8. System.out.println(user2.hashCode());
  9. HashMap<User,String> map = new HashMap<User,String>();
  10. map.put(user1,"123");
  11. map.put(user2,"456");
  12. System.out.println(map.get(user1));
  13. System.out.println(map.get(user2));
  14. }
  15.  
  16. }
  17.  
  18. class User{
  19. private String name;
  20. private String password;
  21. private String address;
  22.  
  23. @Override
  24. public boolean equals(Object o) {
  25. if (this == o) return true;
  26. if (o == null || getClass() != o.getClass()) return false;
  27. User user = (User) o;
  28. return Objects.equals(name, user.name) &&
  29. Objects.equals(password, user.password) &&
  30. Objects.equals(address, user.address);
  31. }
  32.  
  33. }

输出结果:

  1. true
  2. 1163157884
  3. 1956725890
  4. 123
  5. 456

有没有发现问题出在哪里?

用equals比较说明对象相同,但是在HashMap中却以不同的对象存储(没有重写hascode值,两个hascode值,在他看来就是两个对象)。

到底这两个对象相等不相等?
说明必须重写hashCode()的重要性,

接下来重写重写equals方法和hashCode方法,再比较

  1. public class Test {
  2.  
  3. public static void main(String[] args) {
  4. User user1 = new User();
  5. User user2 = new User();
  6. System.out.println(user1.equals(user2));
  7. System.out.println(user1.hashCode());
  8. System.out.println(user2.hashCode());
  9. HashMap<User,String> map = new HashMap<User,String>();
  10. map.put(user1,"123");
  11. map.put(user2,"456");
  12. System.out.println(map.get(user1));
  13. System.out.println(map.get(user2));
  14. }
  15.  
  16. }
  17.  
  18. class User{
  19. private String name;
  20. private String password;
  21. private String address;
  22.  
  23. @Override
  24. public boolean equals(Object o) {
  25. if (this == o) return true;
  26. if (o == null || getClass() != o.getClass()) return false;
  27. User user = (User) o;
  28. return Objects.equals(name, user.name) &&
  29. Objects.equals(password, user.password) &&
  30. Objects.equals(address, user.address);
  31. }
  32.  
  33. @Override
  34. public int hashCode() {
  35. return Objects.hash(name, password, address);
  36. }
  37. }

输出结果:

  1. true
  2. 29791  //相同的对象
  3. 29791
  4. 456   //说明以一个值key存储,相同的值
  5. 456

看到这里,你懂了吗? 还不懂,可以自己实现一遍代码。

一文搞懂--Java中重写equals方法为什么要重写hashcode方法?的更多相关文章

  1. 一文搞懂 Java 中的枚举,写得非常好!

    知识点 概念 enum的全称为 enumeration, 是 JDK 1.5 中引入的新特性. 在Java中,被 enum关键字修饰的类型就是枚举类型.形式如下: enum Color { RED, ...

  2. 一文彻底搞懂Java中的环境变量

    一文搞懂Java环境变量 记得刚接触Java,第一件事就是配环境变量,作为一个初学者,只知道环境变量怎样配,在加上各种IDE使我们能方便的开发,而忽略了其本质的东西,只知其然不知其所以然,随着不断的深 ...

  3. 【转】彻底弄懂Java中的equals()方法以及与"=="的区别

    彻底弄懂Java中的equals()方法以及与"=="的区别 一.问题描述:今天在用Java实现需求的时候,发现equals()和“==”的功能傻傻分不清,导致结果产生巨大的偏差. ...

  4. 一文搞懂 js 中的各种 for 循环的不同之处

    一文搞懂 js 中的各种 for 循环的不同之处 See the Pen for...in vs for...of by xgqfrms (@xgqfrms) on CodePen. for &quo ...

  5. 轻松搞懂Java中的自旋锁

    前言 在之前的文章<一文彻底搞懂面试中常问的各种“锁”>中介绍了Java中的各种“锁”,可能对于不是很了解这些概念的同学来说会觉得有点绕,所以我决定拆分出来,逐步详细的介绍一下这些锁的来龙 ...

  6. 一文搞懂Java引用拷贝、浅拷贝、深拷贝

    微信搜一搜 「bigsai」 专注于Java和数据结构与算法的铁铁 文章收录在github/bigsai-algorithm 在开发.刷题.面试中,我们可能会遇到将一个对象的属性赋值到另一个对象的情况 ...

  7. 一文搞懂Java引用拷贝、深拷贝、浅拷贝

    刷题.面试中,我们可能会遇到将一个对象的属性赋值到另一个对象的情况,这种情况就叫做拷贝.拷贝与Java内存结构息息相关,搞懂Java深浅拷贝是很必要的! 在对象的拷贝中,很多初学者可能搞不清到底是拷贝 ...

  8. 彻底搞懂Java中equals和==的区别

    java当中的数据类型和“==”的含义: 1.基本数据类型(也称原始数据类型) :byte,short,char,int,long,float,double,boolean.他们之间的比较,应用双等号 ...

  9. 一文搞懂Java/Spring/Dubbo框架中的SPI机制

    几天前和一位前辈聊起了Spring技术,大佬突然说了SPI,作为一个熟练使用Spring的民工,心中一紧,咱也不敢说不懂,而是在聊完之后赶紧打开了浏览器,开始的学习之路,所以也就有了这篇文章.废话不多 ...

随机推荐

  1. MapReduce-WordCountDemo

    /** * @Author: dreamer Q * @Date: 2019/11/4 22:26 * @Version 1.0 * @Discription 使用MapReduce 开发 WordC ...

  2. psfstriptable - 从控制台字体中移走嵌入的Uniocde字符表

    总览 psfstriptable 字体文件 [输出文件] 描述 psfstriptable 命令从 字体文件 或者标准输入(此时的 字体文件 是单个破折号(-))读取一个可能含有嵌入Unicode字体 ...

  3. ViewMode

    一.ViewMode 实现使用场景-Model枚举的情景下, 注意:枚举声明在后台的时候,需要渲染界面,页面表格使用 Bootstrap Table插件-事先通过ajax 渲染(数据库读取值1.2.3 ...

  4. linux shell 指令

    一.文件比较运算符 1. e filename 如果 filename存在,则为真 如: [ -e /var/log/syslog ] 2. -d filename 如果 filename为目录,则为 ...

  5. postgre存储过程或者视图中"::"双冒号是什么意思

    双冒号是类型转换的意思. 比如: '2019-09-10'::date

  6. Java基本数据类型及所占字节大小

    一.Java基本数据类型 基本数据类型有8种:byte.short.int.long.float.double.boolean.char 分为4类:整数型.浮点型.布尔型.字符型. 整数型:byte. ...

  7. Linux进程管理——查看内存的工具

    Linux进程管理——查看内存的工具 一查看内存的工具vmstat vmstat命令:虚拟内存信息vmstat [options] [delay [count]]vmstat 2 5 [root@ce ...

  8. HttpClient之HttpContext使用

    Multiple request sequences that represent a logically related session should be executed with the sa ...

  9. 08-图8 How Long Does It Take(25 分)邻接表和队列

    Given the relations of all the activities of a project, you are supposed to find the earliest comple ...

  10. Distribution money

    Distribution money Accepts: 713 Submissions: 1881 Time Limit: 2000/1000 MS (Java/Others) Memory Limi ...