盘点 HashMap 的实现原理及面试题
1、请你谈谈 HashMap 的工作原理
如果被问到 HashMap 相关的问题,它的工作原理都会被作为面试的开场白,这个时候先装作若有所思的样子冷静一下。首先 HashMap 是基于 hashing 的原理,我们知道 HashMap 有两个常用的方法 put()、get(),将键值对传递给 put() 方法时,它调用键对象的 hashCode() 方法来计算 hashcode,然后找到 bucket 位置来储存值对象。当获取对象时,通过键对象的 equals() 方法找到正确的键值对,然后返回值对象。
一般情况下,肯定会问如果不同的键对象的 hashcode 值相等会出现什么样的情况。他们肯定是存储在同一个位置的链表中的,使用键对象的 equals() 方法找到键值对。
HashMap + 链表 + 红黑树 的图片引用自 开源中国
在 Java1.8 以后,HashMap 在数组、链表的基础上又增加了红黑树的数据结构。在一个数组位置的链表长度大于 8 时数据结构转换为红黑树的结构。
2、HashMap 和 HashTable 的区别有什么?
HashMap 和 HashTable 都实现了 Map 接口,主要的区别集中在线程、同步、速度方面的差别。
HashMap 是非同步的,并且 HashMap 可以存储键值为 null 的对象,允许最多只有一个键可以为 null 对象、允许可以有多个值为 null。
HashMap 是线程不安全的,HashTable 是线程安全的。
因为 HashTable 是多线程的,所以在单线程的情况下,HashMap 的速度要快一些。
HashMap 不能保证存储顺序是不变的。
3、HashMap 和 HashSet 的区别有什么?
两者实现的接口不一样,HashMap 实现的是 Map 接口、HashSet 则实现的是 Set 接口。
HashMap 存储的是键值对、HashSet 存储的是对象。
HashSet 的速度比 HashMap 的要慢一些。
计算 hashcode 值的方式不一样,HashMap 使用键对象来计算、HashSet 使用它本身的对象元素来计算。
4、当两个对象的 HashCode 相同会发生什么?
因为 hashcode 相同,所以它们的 bucket 位置相同,‘碰撞’会发生。因为 HashMap 使用链表存储对象,这个 Entry(包含有键值对的 Map.Entry 对象)会存储在链表中。
5、如果两个键的 HashCode 相同,你如何获取值对象?
当我们调用 get()方法,HashMap 会使用键对象的 hashcode 找到 bucket 位置,然后获取值对象。找到 bucket 位置之后,会调用 keys.equals()方法去找到链表中正确的节点,最终找到要找的值对象。
6、多线程情况下,调整 HashMap 的大小会有什么问题?
由于线程不安全的原因,在多线程条件下调整 HashMap 的大小时会存在多个 HashMap 对象的竞争关系,不知道要给哪一个调整大小。如此一来,多线程情况调整 HashMap 的大小就会陷入死循环的情况,在 Java1.5 以后就增加了 ConcurrentHashMap 的对象解决多线程等问题。
更多精彩前往微信公众号【老王说编程】,专注后端编程实战,原创文章每天更新!
版权声明: 本文为 InfoQ 作者【老王说编程】的原创文章。
原文链接:【http://xie.infoq.cn/article/e7bc8bdab0b75f2292af1c907】。文章转载请联系作者。
评论