强大的HashMap
1、啥玩意????:
不用多说,用于存储key-value键值对的集合对吧。。。每一个键值对也可称为Entry,这些键值对分散存储在一个数组当中,这就是HashMap的主干了。
当然,这些数组的每一个元素的初始值都是null。
2、常用方法之put、get:
2.1、put:
最初,自己只会单纯的使用它,并不知道底层究竟发生了啥,后来,大家都会有个疑问,究竟是如何插入数据的?当键值对的索引冲突时怎么办?索引是无限增长的?初始长度以及扩容呢??????等等等。。。。
put原理简单的理解:插入数据时,会利用一个哈希函数来确定键值对的插入位置(index),由于集合的长度是有限的,当数据量过大时,必定会出现索引冲突的现象,然而当索引冲突时,hashmap是利用链表来解决的,HashMap数组的每一个元素不止是一个Entry对象,也是一个链表的头节点。每一个Entry对象通过Next指针指向它的下一个Entry节点。当新来的Entry映射到冲突的数组位置时,只需要插入到对应的链表即可,当新来的Entry节点插入链表时,使用的是“头插法”(发明者认为后插入的数据被查找的可能性更大)。
2.2、get:
首先通过key计算找到对应的索引位置,由于某个索引可能有多个键值对,这时便通过key从头结点去查找链表中与key一致的数据,最后得到相应的值。
3、实现:
默认长度是16,每次扩容或是手动初始化时,长度必须是2的幂等。
之所以是2的幂等,是因为符合Hash算法的均匀分布的原则。
计算公式(二进制与计算):index = HashCode(Key) & (Length - 1)
1.Hashmap在插入元素过多的时候需要进行Resize,Resize的条件是
HashMap.Size >= Capacity * LoadFactor
2.Hashmap的Resize包含扩容和ReHash两个步骤,ReHash在并发的情况下可能会形成链表环
(较难理解 通往链接:https://mp.weixin.qq.com/s/dzNq50zBQ4iDrOAhM4a70A)