HashMap解析

什么是HashMap

采用数组+链表的结构来实现,允许空KV,非线程安全。

初始参数

  • 初始大小16(大小必定为2的幂数,计算下标的算法为hash&size-1;2的幂数减一的值二进制下所有位数都为1,这样就保证了下标的值为hash的后几位,只要hash本身分布均匀,计算下标的算法就是相对均匀的,使得数据能够均匀分布到数组中)
  • 负载因子0.75(空间利用率与时间复杂度之间的取舍)

赋值操作

添加元素时,根据key的hashcode再hash(根据key的hashcode与hashcode的高16位的hashcode做异或操作得到,加大低位的随机性,保证了hashcode的32位值,只要有一位发生变化,整个hash值就会发生改变),然后根据这个hash值结合数组长度,定位到下标,将key与value包装成Entry(1.8为Node类),放入下标中。如果发生冲突的话,以头插法(1.8为尾插法,头插法在并发扩容时,rehash,可能会形成链表环,导致查找的死循环)添加新元素为链表头结点(1.8为尾结点)。当链表的长度超过8(根据泊松分布,8为极小概率事件)且数组的长度超过64(当数组小于64的时候,数组+链表的方式查询效率更高)的时候,将链表转成红黑树(红黑树是一种近似平衡二叉树,相比其他平衡二叉树,维护平衡的代价相对较低,二叉搜索树在极端情况下会退化成链表),提升查找效率,由O(n)→O(logn);否则就进行扩容操作。

扩容操作

当数组大小超过阈值并且发生hash冲突的时候,会进行扩容操作,扩容为之前的2倍大小。扩容时,当红黑树结点数量小于6的时候从红黑树转成链表。

取值操作

获取数据时,计算key的hash值,然后根据这个hash值再hash并结合数组长度,定位到下标,并通过equals方法对比key查找数据。

删除操作

删除数据时,hash查找,如果是单元素直接置null,链表断开链接,红黑树删除元素再平衡。

缩容操作

没有动态缩容

你可能感兴趣的:(HashMap解析)