HashMap的底层数据结构是数组,如果发生了hash冲突的话,会采用拉链法,将数组中的节点挂载成一个链表,JDK1.8之后如果链表节点数量太多,超过阈值8的话,就会转化为红黑树。因为HashMap在遍历key的时候,如果是链表的话,会循环遍历整个链表,时间复杂度是O(n),效率较低,使用红黑树的话,时间复杂度是O(logn),可以有效提升效率
好像有点跑题了,主要是想说HashMap的底层其实是一个数组,既然是一个数组,必然长度是固定的,也就一定存在扩容的问题。在JDK1.7的时候,是将数组扩容为两倍,然后将HashMap中所有的key重新进行hash寻址然后再放入到新的位置
在JDK1.8的时候,扩容同样是按照两倍的大小进行扩容,同时将hash算法、hash寻址算法进行了优化(可以参考我的这篇文章 HashMap简析)rehash算法,也就是扩容后重新为里面的键值对寻址的算法也优化了
举个例子,首先你得知道hash寻址算法是 index =(n - 1) & hash,n是数组的容量,hash是key的hash值,这里以默认数组长度16来计算
上面进行hash寻址之后,就可以得到key的位置index是12(1100的十进制)