面试1:HashMap为什么要同时重写hashCode()和equals()方法
先放结论: 通过重写的hashcode 直接定位到key 的位置 , 根据重写的equals 保证唯一性。
hashCode()方法主要用来定位元素在数组中的下标位置;
equals()方法主要是在发生hash冲突时,遍历链表,挨个比较元素时,判断两个元素是否相等。
重写hashCode():
保证hashmap键的唯一性
hashmap 初始化的时候是一个table 数组, 默认是16大小 , 然后如果有了hash冲突每一个键值对的下方会有一个链表进行hash冲突的解决方式 。
假如只重写hashcode , 不重写equals :
put ("a" ,"123") ; ---> 存这个的时候调用key 的hashCode , 因为Object的hashcode返回的是内存地址 ,如果不重写hashcode , 那么同样的一个键值对 , 唯一性得不到保证 。
假设上方put ("a" ,"123") ; put成功 ,如果这个时候继续调用一次put ("a" ,"123") ;那么如果没有重写hashCode , 则此时两者都用的Object的hashcode去返回内存地址 , 两者hashcode比较肯定是不同的 ,原因在于不是同一个对象 。
则存储的情况可能是这样的 : 假设table 长度为 6
1 | 2 | 3 | 4 | 5 | 6 |
(a,123) | (a, 123) |
重写equals():
object 的equals 是 比较是否为同一个对象 , 即内存地址是否一样 。
此时我还是 put ("a" ,"123") ; 接着我在put ("b" ,"123") ;两次put 元素 ,假设这两次put的时机刚好key的hash 命中了 ,即发生了hash冲突 , 那么按照hashmap的解决方式 , 用了链表进行冲突位置的连接 , 存储情况如下:
1 | 2 | 3 | 4 | 5 | 6 |
(a, 123) | |||||
(b, 123) |
那么执行过程是 对 a 进行hashcode 的判断 ,知道是在1号位置 , 那么去1号位置 , 发现有两个元素,
一个是(a,123) 、一个是(b,123) , 那我应该怎么判断呢 ? 肯定是用equals 进行判断 。
什么时候需要重写hashcode和equals方法?
在HashMap中存放自定义的键时,就需要重写自定义对象的hashcode和equals方法
如何重写hashcode和equals方法
class Key { private Integer id; public Integer getId() { return id; } public Key(Integer id) { this.id = id; } @Override public int hashCode() { return id.hashCode(); } @Override public boolean equals(Object obj) { if (obj == null || !(obj instanceof Key)) { //instanceof 判断左边最想是否为其右边类的实例 return false; } else { return this.getId().equals(((Key) obj).getId()); //比较两个对象的id值是否相同 } } } public class WithoutHashCode { public static void main(String[] args) { Key k1 = new Key(1); Key k2 = new Key(1); HashMap<Key, String> hashMap = new HashMap<>(); hashMap.put(k1, "Key with id is 1"); System.out.println(hashMap.get(k2)); } }
转载bilibili讲解视频:https://www.bilibili.com/video/BV1u44y1K7GA?spm_id_from=333.337.search-card.all.click
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~