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

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

#头条开新年#

大家好,我是积极分享技术的小米!今天给大家带来一道经典的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中的关键字区分大小写标识符(常见命名规则)1、包名所有字母一律小写。...

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

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

Java错误排行:50种常见bug及如何避免它们(一)

开发Java软件时会遇到很多类型的错误,但是大多数错误是可以避免的。编写代码时,有些错误是次要的失误,但这是很容易纠正的。如果您具有诸如Stackify Retrace之类的错误监视工具,则可以轻松编...

JAVA学习基础之简单JAVA 程序(java简单教程)

第二章、简单JAVA 程序一个简单的JAVA程序(文件名必须与程序中的主类名称一致)Test.java:public class Test{public static void main(String...

公司招聘java工程师(程序员)面试考题

面试题一、单项选择题(每小题2分,共20分)1:下列属于合法的Java标识符是( )A _cat B 5books C +static D -3.141592:在读字符文件Employee.dat时,...

[Android探索之旅] 面向对象和Java基础

读完这篇文章大概需要10分钟“搭建开发环境(which is easy)之前, 得先把面向对象和Java基础说一下。其实, 关于Android开发环境(安装配置Android Studio), 我之前...