HashMap 要点详细记录
HashMap基础
- HashMap存储结构为数组、链表、红黑树(JDK1.8)。
- HashMap由节点Node<K,V>组成。
- HashMap只允许一个key为null和“”,且若为null,hash值会被赋为0,若为“”空字符串,hash值本来就是0。
- 若数组某个节点上的Node>=7,则会将链表进化为红黑树,反之若节点<6则会由红黑树退化为链表。
- HashMap线程不安全,ConcurrentHashMap线程安全。
- 数组初始化长度为16, Load factor负载因子默认值为0.75,不建议修改,除非有特殊情况。
- threshold:HashMap所能容纳的最大数据量的Node(键值对)个数。threshold = length * Load factor。最大数量=数组长度*负载因子。
- HashMap中数组的长度必须为2的幂。
hash方法
- 此方法作用是确定元素在数组的位置下标,需尽量让元素均匀分布,降低时间复杂度减少碰撞,提高hash方法的离散性能,优化查询效率。
- hash方法实现分为3步:
① 取Node的key的hashCode值。
② hashCode与自己的高16位进行异或运算。
③ 拿异或的值对数组长度取余,最终得到下标。 - 哈希运算是一类算法也叫摘要算法,是一种单向散列函数(MD5、SM3等)。作用是输入任意值,通过散列算法固定长度输出。且相同的输入则输出相同,不同的输入大概率输出也不同。所以可以用来检查数据的完整性,保证数据未被篡改。
- JDK1.8将Key的hash值与自身的高16位进行异或运算,目的是可以在数组table的length比较小的时候让高位也参与运算。
- 当length是2的n次方时,h& (length-1)运算等价于对length取余,&比%效率更高。(key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
put方法
- HashMap采用懒加载,实例化时不会有初始容量信息。所以put第一步判断length是否为0或table是否为null。
- 为null,则通过扩容来初始化容量。
- 根据key计算hash得到插入的数组索引值i。
- 判断 table[i] == null
- 为null则插入即可。
- 若不为null,则判断key是否存在,存在则覆盖。
- 若不存在则判断table[i] 是否为treeNode。
- 是红黑树则直接插入键值对 。
- 若否则开始遍历链表插入。
- 遍历过程中判断链表长度是否>=7
- 是则转化为红黑树。
- 否 则还是链表插入即可。
- 遍历过程中若发现key存在则直接覆盖。
- 插入成功后,判断实际存在的键值对数量size是否超多了最大容量threshold,如果超过,进行

HashMap存储结构包含数组、链表和红黑树,适用于JDK1.8。HashMap使用Node存储键值对,当链表长度达到7时转换为红黑树。put方法根据key计算hash插入,超过阈值时会扩容。HashMap线程不安全,可能导致死循环。CurrentHashMap为线程安全的替代,使用分段锁和CAS保证并发安全。
最低0.47元/天 解锁文章
5685





