Java社招面试题:Map的Key你真的了解吗?

createh52个月前 (01-24)技术教程24

#头条开新年#

大家好,我是积极分享技术的小米!今天给大家带来一道经典的Java社招面试题:“能否使用任何类作为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?

接着,面试官进一步追问:“那为什么StringInteger这样的包装类适合作为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最好是不可变的(如StringInteger),否则会导致数据一致性问题。

2、重写规则一致

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

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

3、合理选择Key

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

总结

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

  • 能否使用任何类作为Map的Key?:可以,但必须保证重写hashCode()和equals()方法。
  • 为什么String和Integer适合作为Key?:它们有良好的hashCode()和equals()实现,并且是不可变类。
  • 如果使用自定义类作为Key?:重写hashCode()和equals()方法,确保Key的唯一性和一致性。

END

希望今天的分享对大家有所帮助!如果你喜欢这样的技术干货,记得点个“在看”支持小米哦~

你有没有踩过使用HashMap时Key不合适的坑?欢迎在评论区分享,我们一起探讨!

我是小米,一个喜欢分享技术的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号软件求生,获取更多技术干货!

相关文章

Java中标识符的命名规则(java中标识符的命名规则有哪些)

在 Java 编程中,标识符的命名有着明确且重要的规则。首先,标识符必须以字母、下划线(_)或美元符号($)开头,后续部分可以是字母、数字、下划线或美元符号的组合。这意味着标识符不能以数字开头,否则将...

Java基础之Java标识符有哪些?命名规范是什么?

“这里是云端源想IT,帮你轻松学IT”嗨~ 今天的你过得还好吗?落日余晖的路上总是爱意弥漫别让世俗淹没生活的浪漫和热情- 2023.08.02-Java语言中,对于变量,常量,函数,语句块也有名字,我...

Java中的关系运算符(java的关联关系)

5.1运算符的介绍运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等5.2算术运算符5.2.1介绍算术运算符是对数值类型的变量进行运算的。5.2.2算术运算符分类运算符运算范例结果+正号+55-...

Java初学者需要了解的10个语法细节

语法语法,语法就是语言的法则。汉语有汉语的语法,英语有英语的语法,如果不懂语法那你写出来的句子要不然就是错误,要不然就是生涩难懂。要学习和使用Java语言就要遵守Java语言的规则,要不然你的程序就不...

java 9 集合工厂方法:快速创建只读集合和“标识符优化”

新增的方法调用集合中静态方法 of(),可以将不同数量的参数传输到此工厂方法中。此功能可用于 Set 和 List,也 可用于 Map 的类似形式。此时得到 的集合,是不可变的:List.ofSet....

100个Java工具类之47:唯一标识符UUID

UUID,通用唯一识别码。因为它是根据时间戳和当前机器的物理地址生成的,因此它几乎不会重复。在java中,其主要作用是生成一个唯一标识符。常常被当做数据库表主键使用。根据java.util.UUID的...