普歌-允异团队-HashMap面试题(续)

1.HashMap扩容流程?

  1. HashMap的扩容指的就是数组的扩容, 因为数组占用的是连续内存空间,所以数组的扩容只能新开一个新的数组,然后把老数组上的元素转移到新数组上来
  2. 在HashMap中也是一样,先新建一个2倍数组大小的数组
  3. 然后遍历老数组上的每一个位置,如果这个位置上是一个链表,就把这个链表上的元素转移到新数组上去
  4. 在这个过程中就需要遍历链表,jdk7和jdk8在这个实现时是有不一样的
  • jdk7就是简单的遍历链表上的每一个元素,然后按每个元素的hashcode结合新数组的长度重新计算得出一个下标,而重新得到的这个数组下标很可能和之前的数组下标是不一样的,这样子就达到了一种效果,就是扩容之后,某个链表会变短,这也就达到了扩容的目的,缩短链表长度,提高了查询效率
  • jdk8中,因为涉及到红黑树,比较复杂,jdk8中会用到一个双向链表来维护红黑树中的元素,所以jdk8中在转移某个位置上的元素时,会去判断如果这个位置是一个红黑树,那么会遍历该位置的双向链表,遍历双向链表统计哪些元素在扩容完之后还是原位置,哪些元素在扩容之后在新位置,这样遍历完双向链表后,会得到两个子链表,一个放在原下标位置,一个放在新下标位置,如果原下标位置或新下标位置没有元素,则红黑树不用拆分,否则判断这两个子链表的长度,如果超过八,则转成红黑树放到对应的位置,否则把单向链表放到对应的位置。
  1. 元素转移完了之后,在把新数组对象赋值给HashMap的table属性,老数组会被回收到。

2.HashMap的数组的大小是2的幂次方

key-value对需要存储到数组中时,需要生成一个数组下标(不能越界)。在HashMap中,先得到key的hashcode(数字)
通过hashcode & (table.length - 1) 运算得到一个数组下标

  • 与运算计算出来一个数组下标的,而不是通过取余,与运算相比于取余运算速度更快
  • 前提条件,数组的长度是2的幂次方数。

HashMap面试题


  • 作者:麦克猫Cat

  • 本文版权归作者和CSDN共有,欢迎交流

猜你喜欢

转载自blog.csdn.net/weixin_52309367/article/details/115567160
今日推荐