Map的Key你真的了解吗?

开发 前端
如果你使用一个可变对象作为Key,比如一个List,情况会变得复杂。如果在存入HashMap后,你修改了List的内容,它的hashCode就会改变,导致HashMap无法正确找到存储的位置。

何类作为Map的Key?为什么HashMap中String、Integer这样的包装类适合作为Key?如果使用Object作为HashMap的Key,应该怎么办?” 这个问题看似简单,但实际上涉及到HashMap的核心机制,面试中说得清楚绝对能让面试官眼前一亮!

话不多说,让我们通过一个小故事,边学边聊。

初识问题:能否使用任何类作为Map的Key?

故事从小明找工作说起。小明在面试时被问到:“你能用任何类作为Map的Key吗?”

小明想了想,答:“理论上可以吧,但会有坑。”

没错,理论上任何类都可以作为Map的Key。但是!能否真正高效和正确地使用,得满足两个条件:

  • 必须重写hashCode()方法:这是因为HashMap基于哈希表实现,hashCode()决定了对象的存储位置。
  • 必须重写equals()方法:当两个对象的hashCode相同,HashMap会使用equals()方法来判断它们是否真的相等。

如果你用的类没有重写这两个方法,HashMap就可能无法正确判断Key是否相等,导致奇怪的行为。比如,明明存进去了,却取不出来。

为什么String和Integer适合作为Key?

接着,面试官进一步追问:“那为什么String和Integer这样的包装类适合作为Key呢?”

小明顿时慌了,但冷静下来,他回忆起学过的知识,侃侃而谈。

String

  • String的hashCode()实现简单明了,基于内容计算哈希值。
  • 它的equals()方法也是内容比较,完全符合HashMap的需求。
  • 不可变性:String是不可变类,哈希值一旦计算,就不会因内容变化而失效。

Integer

  • Integer的hashCode()直接返回它的值,简单高效。
  • equals()也是基于值的比较。
  • 同样是不可变的包装类,Key的状态不会因外部修改而改变。

对比之下,如果你使用一个可变对象作为Key,比如一个List,情况会变得复杂。如果在存入HashMap后,你修改了List的内容,它的hashCode就会改变,导致HashMap无法正确找到存储的位置。

如果使用Object作为Key,该怎么办?

这时,面试官继续刁难:“假如我想用自己的类Person作为Key呢?”

小明心里有底了,他微微一笑:“那就得自己实现hashCode()和equals()方法了。”

如何实现?

以下是小明举的例子:

图片图片

  • hashCode():使用Objects.hash()方法将name和age的值组合成一个哈希值,保证哈希分布的均匀性。
  • equals():确保当两个对象的name和age都相同时,它们被认为是相等的。

避坑指南:Key需要注意哪些问题?

1、不可变性

Key最好是不可变的(如String和Integer),否则会导致数据一致性问题。

2、重写规则一致

如果你重写了equals(),就必须重写hashCode(),并保证规则一致:

  • 如果两个对象相等(equals()返回true),它们的hashCode必须相等。
  • 如果两个对象不相等,它们的hashCode尽量不同。

3、合理选择Key

如果使用复杂对象作为Key,确保它的字段值不会频繁变动,否则建议使用唯一标识符(如ID)。

总结

面试结束后,小明总结道:

  • 能否使用任何类作为Map的Key?:可以,但必须保证重写hashCode()和equals()方法。
  • 为什么String和Integer适合作为Key?:它们有良好的hashCode()和equals()实现,并且是不可变类。
  • 如果使用自定义类作为Key?:重写hashCode()和equals()方法,确保Key的唯一性和一致性。
责任编辑:武晓燕 来源: 软件求生
相关推荐

2022-07-26 00:00:22

HTAP系统数据库

2014-04-17 16:42:03

DevOps

2021-01-15 07:44:21

SQL注入攻击黑客

2021-11-09 09:48:13

Logging python模块

2014-11-28 10:31:07

Hybrid APP

2019-09-16 08:40:42

2020-02-27 10:49:26

HTTPS网络协议TCP

2023-03-16 10:49:55

2021-11-26 08:07:16

MySQL SQL 语句数据库

2023-11-01 13:48:00

反射java

2018-01-06 10:38:51

Ping抓包 ICMP协议

2019-11-06 09:52:01

JavaScript单线程非阻塞

2017-10-18 22:01:12

2023-10-24 08:53:24

FutureTas并发编程

2022-12-12 08:46:11

2012-05-31 09:56:54

云安全

2015-07-31 10:35:18

实时计算

2022-03-14 07:53:27

ELTETL大数据

2024-02-02 08:50:20

Node.js元数据自动化

2024-01-29 10:09:59

数据库INT(3)INT(11)
点赞
收藏

51CTO技术栈公众号