看多了各种各样源码介绍,属性分析,让我们来点新花样,以面试官一问一答的方式看这篇文章

“你用过HashMap吗?” “什么是HashMap?你为什么用到它?”

几乎每个人都会回答“是的”,然后回答HashMap的一些特性,譬如HashMap可以接受null键值和值,而HashTable则不能;HashMap是非synchronized;HashMap很快;以及HashMap储存的是键值对等等。这显示出你已经用过HashMap,而且对它相当的熟悉。面试官这个时候来个急转直下,从此刻开始问出一些刁钻的问题,关于HashMap的更多基础的细节。面试官可能会问出下面的问题:

“你知道HashMap的工作原理吗?” “你知道HashMap的get()方法的工作原理吗?”

你也许会回答“我没有详查标准的Java API,你可以看看Java源代码或者Open JDK。”“我可以用Google找到答案。”
但一些面试者可能可以给出答案,“HashMap是基于hashing的原理,我们使用put(key, value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。当我们给put()方法传递键和值时,我们先对键调用hashCode()方法,返回的hashCode用于找到bucket位置来储存Entry对象。”这里关键点在于指出,HashMap是在bucket中储存键对象和值对象,作为Map.Entry。这一点有助于理解获取对象的逻辑。如果你没有意识到这一点,或者错误的认为仅仅只在bucket中存储值的话,你将不会回答如何从HashMap中获取对象的逻辑。这个答案相当的正确,也显示出面试者确实知道hashing以及HashMap的工作原理。但是这仅仅是故事的开始,当面试官加入一些Java程序员每天要碰到的实际场景的时候,错误的答案频现。下个问题可能是关于HashMap中的碰撞探测(collision detection)以及碰撞的解决方法:

“当两个对象的hashcode相同会发生什么?”

从这里开始,真正的困惑开始了,一些面试者会回答因为hashcode相同,所以两个对象是相等的,HashMap将会抛出异常,或者不会存储它们。然后面试官可能会提醒他们有equals()和hashCode()两个方法,并告诉他们两个对象就算hashcode相同,但是它们可能并不相等。一些面试者可能就此放弃,而另外一些还能继续挺进,他们回答“因为hashcode相同,所以它们的bucket位置相同,‘碰撞’会发生。因为HashMap使用LinkedList存储对象,这个Entry(包含有键值对的Map.Entry对象)会存储在LinkedList中。”这个答案非常的合理,虽然有很多种处理碰撞的方法,这种方法是最简单的,也正是HashMap的处理方法。但故事还没有完结,面试官会继续问:

“如果两个键的hashcode相同,你如何获取值对象?”

当我们调用get()方法,HashMap会使用键对象的hashcode找到bucket位置,然后获取值对象。面试官提醒他如果有两个值对象储存在同一个bucket,他给出答案:将会遍历LinkedList直到找到值对象。面试官会问因为你并没有值对象去比较,你是如何确定确定找到值对象的?除非面试者直到HashMap在LinkedList中存储的是键值对,否则他们不可能回答出这一题。
其中一些记得这个重要知识点的面试者会说,找到bucket位置之后,会调用keys.equals()方法去找到LinkedList中正确的节点,最终找到要找的值对象。完美的答案!
许多情况下,面试者会在这个环节中出错,因为他们混淆了hashCode()和equals()方法。因为在此之前hashCode()屡屡出现,而equals()方法仅仅在获取值对象的时候才出现。一些优秀的开发者会指出使用不可变的、声明作final的对象,并且采用合适的equals()和hashCode()方法的话,将会减少碰撞的发生,提高效率。不可变性使得能够缓存不同键的hashcode,这将提高整个获取对象的速度,使用String,Interger这样的wrapper类作为键是非常好的选择
如果你认为到这里已经完结了,那么听到下面这个问题的时候,你会大吃一惊。

“如果HashMap的大小超过了负载因子(load factor)定义的容量,怎么办?”

除非你真正知道HashMap的工作原理,否则你将回答不出这道题。默认的负载因子大小为0.75,也就是说,当一个map填满了75%的bucket时候,和其它集合类(如ArrayList等)一样,将会创建原来HashMap大小的两倍的bucket数组,来重新调整map的大小,并将原来的对象放入新的bucket数组中。这个过程叫作rehashing,因为它调用hash方法找到新的bucket位置
如果你能够回答这道问题,下面的问题来了:

“你了解重新调整HashMap大小存在什么问题吗?”

你可能回答不上来,这时面试官会提醒你当多线程的情况下,可能产生条件竞争(race condition)。
当重新调整HashMap大小的时候,确实存在条件竞争,因为如果两个线程都发现HashMap需要重新调整大小了,它们会同时试着调整大小。在调整大小的过程中,存储在LinkedList中的元素的次序会反过来,因为移动到新的bucket位置的时候,HashMap并不会将元素放在LinkedList的尾部,而是放在头部,这是为了避免尾部遍历(tail traversing)。如果条件竞争发生了,那么就死循环了。这个时候,你可以质问面试官,为什么这么奇怪,要在多线程的环境下使用HashMap呢?:)

总结:HashMap的工作原理
  HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用LinkedList来解决碰撞问题,当发生碰撞了,对象将会储存在LinkedList的下一个节点中。 HashMap在每个LinkedList节点中储存键值对对象。
  当两个不同的键对象的hashcode相同时会发生什么? 它们会储存在同一个bucket位置的LinkedList中。键对象的equals()方法用来找到键值对。

HashMap使用注意点:

  • 初始化值
    在《阿里Java开发手册》一书中提到,

    默认情况下HashMap的容量是16,但是,如果用户通过构造函数指定了一个数字作为容量,那么Hash会选择大于该数字的第一个2的幂作为容量。(3->4、7->8、9->16)

  • key的设计,如果是自定义key,需要实现equals()和hashCode()方法

  • 1.8以后,当链表的长度超过8个时,会切换成红黑树管理,因为链表查询很慢

HashMap趣味问答相关推荐

  1. ai中如何插入签名_如何在微信公众号文章排版中插入趣味问答互动样式?

    每天都有一批运营人,在为微信公众号文章的互动抓破了脑袋.绞尽脑汁想尽办法让用户点进了文章,奈何缺乏互动导致用户很快离开.有小伙伴在阅读其他公众号文章的时候发现公众号文章里,有很有趣的互动模式,就是趣味 ...

  2. HashMap精选问答

    关于HashMap HashMap是使用频率最高的映射(键值对)数据类型.JDK1.8对HashMap底层的实现进行了优化,例如引入红黑树的数据结构和扩容的优化等. Map四大实现类:知多D Hash ...

  3. HashMap的问答总结

    关于Hash的14问 Q0:HashMap是如何定位下标的? A:先获取Key,然后对Key进行hash,获取一个hash值,然后用hash值对HashMap的容量进行取余(实际上不是真的取余,而是使 ...

  4. 基于H5的头脑风暴趣味游戏设计(趣味问答)

    3.2系统功能需求分析 本课题中所涉及到的游戏并不是"单机"游戏,游戏题目是可以由管理员进行管理维护的,所以本课题中的角色不仅有游戏玩家,还有系统管理员角色.下面对这两个角色的功能 ...

  5. 公布获奖名单推文文案_国学养正·趣味竞答获奖名单公布啦

    国学养正·趣味竞答获奖名单公布啦!!! 潮州市图书馆阅读推广 潮州市图书馆阅读推广 微信号 czstsg 功能介绍 为读者提供本馆各类公益活动信息发布.志愿者服务信息活动咨询.阅读推广等服务 收录于话 ...

  6. 百度DuerOS联手蓝港发布“小青智趣”,布局AI语音问答游戏

    李根 发自 凹非寺  量子位 报道 | 公众号 QbitAI AI语音问答游戏也有来了,这次是百度度秘与蓝港科技走到了一起. 百度度秘与蓝港科技共同宣布"小青智趣计划",联手布局语 ...

  7. Java项目:在线美食网站系统(java+SSM+jsp+mysql+maven)

    源码获取:博客首页 "资源" 里下载! 一.项目简述 功能:用户的注册登录,美食浏览,美食文化,收藏百 科,趣味问答,食谱等等功能等等. 二.项目运行 环境配置: Jdk1.8 + ...

  8. 100个iOS开发/设计面试题汇总,你将如何作答?

    原文: http://www.csdn.net/article/2015-01-19/2823604-ios-interview-questions 常见问题 你昨天/这周学习了什么? 你为什么热衷于 ...

  9. 100道ios面试题目的总结体会

    常见问题 - 你昨天/这周学习了什么? 昨天到目前为止学习了图片,以及视频上传的压缩处理,还有就是instruments上面的一些用法,还有一个自动化测试工具,进行软件的测试处理 常见问题 - 你为什 ...

最新文章

  1. mina、netty消息边界问题(采用换行符)
  2. 当我们在谈深度学习时,到底在谈论什么(二)--转
  3. 解题:POI 2013 Triumphal arch
  4. 【原】webpack--loaders,主要解释为什么需要loaders和注意事项
  5. jar包 jdk 停_一文读懂jar包的小秘密
  6. 用JavaScript 制作多彩的弹出式说明窗口
  7. Google的Java常用类库 Guava
  8. 前端软件sublime的一些常用快捷键
  9. arcgis怎么压缩tif文件_PDF文件怎么压缩?两招帮你解决PDF压缩难题!
  10. 人在职场,身不由己?
  11. python 拓扑排序_python拓扑排序算法实现
  12. UE4蓝图API翻译【节点】---? Is Valid
  13. QT 加载歌词LRC文件
  14. C语言中delay的用法
  15. 光滑曲线_对第一/二型曲线/曲面积分的小总结
  16. 全新整理:微软、谷歌、百度等公司经典面试100题[第1-60题]
  17. Google VP8 Code 首次深入技术分析 1
  18. 《王阳明心学营销》营销落地-知行合一
  19. AV3680A天馈线测试仪使用方式
  20. 筹码分布的计算方法笔记

热门文章

  1. python:app稳定性测试工具
  2. YYText识别链接点击效果和输出点击的内容
  3. 学习从USGS中下载真实世界高度图并导入Houdini
  4. 分享 10 个 Tailwind CSS UI 站点,助你快速启动项目
  5. 兰州理工大学c语言试题答案,兰州理工大学c语言题库
  6. 字节跳动,华为,阿里巴巴,小米,腾讯2020大厂面试经历系列之(面试题篇)
  7. Unity 粒子特效、材质发光 HDR ShaderGraph图文教程
  8. 白塞氏病如何避免加重
  9. 计算机网络知识点(1)
  10. Scratch(二):猫猫开始运动啦