HashMap你了解多少

  

HashMap几乎是面试必问的知识,对于HashMap面试是你真的能从容面对吗?相信如果你去面试知名互联网公司的时候,决对不会只是问问你HashMap的数据结构这么简单的问题。我收集了最近老大在面试过程中关于HashMap常问的几个问题:

  

1。为什么HashMap是2的幂次方?

  
 <代码>新HashMap(14);  
  

HashMap是由数组+链表(1.8还有红黑树)来实现的,那么上面这行代码它执行后,创建的数组大小是多少呢?
追踪源码可以看到它会执行这样一个函数来返回数组大小的:

  
 <代码>静态最终int tableSizeFor (int帽){
  int (n=帽- 1;
  |=n祝辞祝辞祝辞1;
  |=n祝辞祝辞祝辞2;
  |=n祝辞祝辞祝辞4;
  |=n祝辞祝辞祝辞8;
  |=n祝辞祝辞祝辞16;
  返回(n & lt;0)?1:(n祝辞=MAXIMUM_CAPACITY) ?MAXIMUM_CAPACITY: n + 1;
  } 
  

 HashMap你了解多少“> <br/>图解:</p>
  <ul>
  <李>第一次右移并且或运算,可以保证从左到右第一位1后面再多出来一个1 </李>
  <李>第二次右移并且或运算,可以保证从左到右再多出两个1 </李>
  <李>以此类推,因为java中int值是4个字节,32位的,所以最后移16位的时候,足以保证2 ^ 32这种情况的出现,李</>
  <李>
  <p>通过这个函数的运算,可以将我们传入的14运算得到16日也就是大于14的最小的2的n次幂。</p>
  李</>
  </ul>
  <p> <强>上面说明了数组大小最后会保证是2的n次幂,那么接下来说说为什么要保证是2的n次幂</强> </p>
  <pre> <代码>静态int indexFor (int, int长度){
  返回h,(长度是1);
  }</代码> </pre>
  <p>在jdk1.7的时候,在把元素时,会执行这样一段代码片段,它的用意就是数据长度与hashCode值取余运算。那既然是取余,为什么不直接用%号呢?是因为位运算要比%运算高效很多。</p>
  <p> <强>那既然是,运算,又为什么非要保证长度是2 ^ n呢? </强> <br/> <img src=

  
      <李>长度是2 ^ n - 1的话,可以保证,的结果是在哈希表的大小范围内,李   <李>,运算与%取模的结果可以保证一致,李   
  

2。为什么HashMap的扩容因子是0.75 ?

  

加载因子是非常重要的一块,如果加载因子太大,假如为1,那么从空间利用率倒是上去了,但是时间效率就降低了。
如果加载因子太小,倒导致hashmap频繁的扩容操作,每次扩容都非常耗性能,
好吧!说了就像没说一样,关于这个问题我也只能抛砖引玉,
其实是这样的:

  
 <代码>因为TreeNodes两倍大小的普通节点,我们
  *使用alt=" HashMap你了解多少"> 

  

4。jdk1.8扩容时会产生死循环吗?

  
 <代码> NodeloHead=null, loTail=零;
  NodehiHead=null, hiTail=零;
  Node下一个;
  {做
  下一个=e.next;
  如果(e。散列,oldCap)==0) {
  如果(loTail==null)
  loHead=e;
  其他的
  loTail。下一个=e;
  loTail=e;
  }
  其他{
  如果(hiTail==null)
  hiHead=e;
  其他的
  hiTail。下一个=e;
  hiTail=e;
  }
  },(下)(e=!=null);
  如果(loTail !=null) {
  loTail。下一个=零;
  打开[j]=loHead;
  }
  如果(hiTail !=null) {
  hiTail。下一个=零;
  打开[j + oldCap]=hiHead;
  } 
  

看下方图文分析:
 HashMap你了解多少

  

所以,jdk1.8中的HashMap在扩容时就不会产生死锁了!

  

5。为什么是链表长度达到8时转为红黑树?

  

首先,TreeNode节点的占用空间的大小是链表节点的两倍,只有当容器达到8的时候才转为红黑树,为什么是8呢,在第二个问题中已经说明了,根据泊松分布可以看的出,链表节点是很难达到长度为8的时候的,如果真有特殊情况达到8了,那么才将链表转为红黑树;
转为红黑树时还有个要求,就是hashMap中的元素个数达到64。

  

6。jdk1.8 HashMap是线程安全的吗?

  

JDK1.8HashMap虽然能够尽大的避免扩容时死循环问题,但是,HashMap仍然是线程不安全的,例如:线程在把元素时,线程B进行扩容;
之所以不安全的原因是多线程会操作同一实例变化,导致变量状态不一致。

HashMap你了解多少