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

文章探讨了使用HashMap时为何需要重写对象的hashCode和equals方法。通过哈希表的原理,解释了哈希查找的高效性,并通过实例展示了哈希碰撞的处理方式,如开放地址法和链地址法。当使用自定义对象作为HashMap的键时,不重写这两个方法会导致查找失败,因为默认的hashCode和equals基于对象的内存地址。正确的做法是根据对象的业务属性重写这些方法,确保哈希值和相等性判断的准确性。
摘要由CSDN通过智能技术生成

引言

以前面试的时候被面试官问到过这样一个问题:

你有没有重写过 hashCode 方法?

心里想着我没事重写哪玩意干啥,能不写就不写。嘴上当然没敢这么说,只能略表遗憾的说抱歉,我没写过。

撇了面试官一眼,明显看到他对这个回答不满意,但是这已经触及到我的知识盲点了,我也很惭愧,可是确实没有重写过,咱也不能胡扯不是。

然后他又问到另外一个问题:

你在用 HashMap 的时候,键(Key)部分,有没有放过自定义对象?

我说我放过,很自信的说我放过(其实我忘了我有没有放过),但是不能怂啊,第一个都不会了,第二个再说不会哪不是直接拜拜要走人了吗?

面试官狡猾的笑了,说是你既然没有重写过 hashCode 方法,你怎么把自定义对象放进去的?

我勒个去,原来你在这等着我呢,没想到这还是个连环炮,惹不起惹不起,认怂三连

97ff0e42d3de8e26b5386bee55253629.png

不过不会就学,不懂就问,这一直都是咱程序猿优秀的素养,今天就干脆从 Hash 表学起,讲述 HashMap 的存取数据规则,由此来搞定上述问题的答案。

通过 Hash 算法来了解 HashMap 对象的高效性

我们先复习数据结构里的一个知识点:

在一个长度为 n(假设是100)的线性表(假设是 ArrayList)里,存放着无序的数字;如果我们要找一个指定的数字,就不得不通过从头到尾依次遍历来查找,这样的平均查找次数是 n / 2(这里是50)。

我们再来观察 Hash 表(这里所说的 Hash 表纯粹是数据结构上的概念,和 Java 无关)。

哈希表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值即 key,即可查找到其对应的值。

它的平均查找次数接近于 1,代价相当小。

使用哈希查找有两个步骤:

  1. 使用哈希函数将被查找的键转换为数组的索引:在理想的情况下,不同的键会被转换为不同的索引值,但是在有些情况下我们需要处理多个键被哈希到同一个索引值的情况。所以哈希查找的第二个步骤就是处理冲突
  2. 处理哈希碰撞冲突:有很多处理哈希碰撞冲突的方法,本文后面会介绍拉链法和线性探测法。

既然哈希查找第一步就是使用哈希函数将键映射成索引,那我们就先假设一个 Hash 函数是x * x % 5,(当然实际编程中不可能用这么简单的 Hash 函数,一般选择的哈希函数都是要易于计算并且能够均匀分布所有键的,这里纯粹为了说明方便),然后假设 Hash 表是一个长度是 11 的线性表。

接下来如果我们如果要把 6 放入其中,那么我们首先会对 6 用 Hash 函数计算一下,结果是 1,所以我们就把 6 放入到索引号是 1 这个位置。同样如果我们要放数字 7,经过 H

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值