HashMap的k放过自定义对象么?

当我们把自定义对象存入HashMap中时,如果不重写hashcode和equals这两个方法,会得不到预期的结果。

class Key{private Integer id;public Integer getId() {return id;}public Key(Integer id) {this.id = id;}
}
public class WithoutHashCode{public static void main(String[] args){//定义两个对象,并声明他俩的id全是1Key k1 = new Key(1);Key k2 = new Key(1);HashMap<Key,String> map = new HashMap<Key,String>();map.put(k1, "Key with id is 1");System.out.println(map.get(k2));}
}

在这里把k1对象作为键put进HashMap,再用k2来get出来并打印。如果没有重写hashcode和equals方法,最终只能得到一个null。
原因很简单,由于我们没有重写hashcode方法,所以在往HashMap中放入k1时依旧调用的是Object类的hashcode方法,返回的是k1对象的内存地址。如果是用map.get(k1)来查找,就能很快得到value值。
但遗憾的是,我们偏偏是用的k2来get。Object的hashcode方法返回的是k2的内存地址,肯定和k1的不相同,换句话说就是他俩的hash值不同,所以不能用k2的hash值拿到k1的value。

重写hashCode和equals方法

class Key{private Integer id;public Integer getId() {return id;}public Key(Integer id) {this.id = id;}@Overridepublic boolean equals(Object o) {if (o==null || !(o instanceof Key)){return false;}else {return this.getId().equals(((Key)o).getId());}}@Overridepublic int hashCode() {return id.hashCode();}
}

只重写了hashCode方法后,这里的hashCode方法return的是id的hashCode值。因为我们之前将两个对象的id都设为1,所以他俩的hash值是一样的。
接下来我们再去map.get(k2),会不会拿到value呢?结果还是null。目瞪狗呆有木有?为啥嘞?不是都已经使他俩的hashCode相同了嘛?因为我们只是重写了hashCode方法,并没有重写equals方法啊。不要忘了,HashMap是用链地址法来处理碰撞冲突的。也就是说,某一条链表上的所有的元素的hashCode返回的hash值全是一样的。只重写hashCode方法只能证明k1和k2的hash值相同,当时并不代表他俩就是相等。没有重写equals方法,又是会调用Object类中的equals方法,判断的依旧是两个对象的内存地址!

涨姿势了…

项目中经常会用到HashMap,所以在面试中被问到的频率也是比较高的。如果要在HashMap中的k存放自定义对象,就一定要重写hashcode和equals两个方法,来覆盖掉Object类中的同名方法!

HashMap存自定义对象为什么要重写 hashcode 和 equals 方法?相关推荐

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

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

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

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

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

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

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

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

  5. 重写hashcode和equals方法

    一.前言 我们都知道,要比较两个对象是否相等时需要调用对象的equals()方法,即判断对象引用所指向的对象地址是否相等,对象地址相等时,那么与对象相关的对象句柄.对象头.对象实例数据.对象类型数据等 ...

  6. Hibernate中用到联合主键的使用方法,为何要序列化,为何要重写hashcode 和 equals 方法...

    联合主键用Hibernate注解映射方式主要有三种: 第一.将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,再将该类注解为 ...

  7. Java重写hashcode()与equals()方法

    一. hashCode 1. 基本概念 hashCode 是 JDK 根据对象的地址算出来的一个 int 数字(对象的哈希码值),代表了该对象再内存中的存储位置. hashCode() 方法是超级类 ...

  8. hibernate中联合主键要同时重写hashCode()和equals()方法

    关于联合主键 联合主键为什么要重写equals方法和hashCode方法,是为了保证唯一性 1.在数据库保证唯一性是使用的联合主键 2.把一系列的对象放到内存的时候,为了区分同名对象,数据库是使用联合 ...

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

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

最新文章

  1. 机器的深度学习究竟有多“深”?
  2. mysql主从复制gtid_详解MySQL主从复制实战 - 基于GTID的复制
  3. vue 仿二手交易app_项目vue2.0仿外卖APP(七)
  4. 安装 esl php 模块,FreeSWITCH 安装配置的 各种坑, 填坑
  5. 搭建spring MVC项目
  6. firefox火狐浏览器怎么清除缓存 火狐浏览器清理cookie教程
  7. qgis oracle,用 QGIS 画矢量交通路线图
  8. android studio Cmake undefine func
  9. dbcc dbreindex server sql_SQL Server数据库碎片整理
  10. JS中的立即执行函数
  11. javascript中的XML
  12. 最近,华为应用市场上线了一个服务
  13. lammps教程:minimize命令使用详解
  14. c语言双人贪吃蛇-基于图形库实现
  15. sqlserver 查询 oracle 语法,Oracle/SQLServer 跨库查询
  16. 美元对人民币汇率的大数据分析与预测
  17. 安利个神器, Python 脚本可轻松打包为 exe
  18. 服务器被劫持是什么意思
  19. Android 第三次作业 contentprovider与resolver
  20. 论文《Depth Estimation From a Light Field Image Pair With a Generative Model》学习

热门文章

  1. 使用navicat premium将数据库从Oracle迁移到SQL Server,或从Oracle迁移到MySQL
  2. 如何正确处理Android6.0+的运行时权限申请
  3. C4D中重点、难点分析
  4. 《JavaScript应用程序设计》一一3.2 流式JavaScript
  5. php生成sitemap
  6. gecco 1.1.0稳定版发布,易用的轻量化爬虫
  7. Start Developing iOS Apps Today系列(十二)
  8. 使用EntityFramework6连接MySql数据库(db first方式)
  9. KVM基础功能——Cpu配置
  10. 十步优化SQL Server中的数据访问