盘点 HashMap 的实现原理及面试题

1、请你谈谈 HashMap 的工作原理

如果被问到 HashMap 相关的问题,它的工作原理都会被作为面试的开场白,这个时候先装作若有所思的样子冷静一下。首先 HashMap 是基于 hashing 的原理,我们知道 HashMap 有两个常用的方法 put()、get(),将键值对传递给 put() 方法时,它调用键对象的 hashCode() 方法来计算 hashcode,然后找到 bucket 位置来储存值对象。当获取对象时,通过键对象的equals() 方法找到正确的键值对,然后返回值对象。

一般情况下,肯定会问如果不同的键对象的 hashcode 值相等会出现什么样的情况。他们肯定是存储在同一个位置的链表中的,使用键对象的 equals() 方法找到键值对。

image.png

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 的对象解决多线程等问题。

更多精彩前往微信公众号【老王说编程】,专注后端编程实战,原创文章每天更新!

image.png

你可能感兴趣的:(盘点 HashMap 的实现原理及面试题)