④如果该位置不为null,则判断key是否一样(hashCode和equals),如果一样则直接覆盖value
⑤如果key不一样,则判断该元素是否为红黑树的节点,如果是,则直接在红黑树中插入键值对
⑥如果不是红黑树的节点,则就是链表,遍历这个链表执行插入操作,如果遍历过程中若发现key已存在,直接覆盖value即可。
如果链表的长度大于等于8且数组中元素数量大于等于阈值64,则将链表转化为红黑树,(先在链表中插入再进行判断)
如果链表的长度大于等于8且数组中元素数量小于阈值64,则先对数组进行扩容,不转化为红黑树。
⑦插入成功后,判断数组中元素的个数是否大于阈值64(threshold),超过了就对数组进行扩容操作。
get操作:
①计算key的hashCode的值,找到key在数组中的位置
②如果该位置为null,就直接返回null
③否则,根据equals()判断key与当前位置的值是否相等,如果相等就直接返回。
④如果不等,再判断当前元素是否为树节点,如果是树节点就按红黑树进行查找。
⑤否则,按照链表的方式进行查找。

2.HashMap的扩容机制

3.HashMap的初始容量为什么是16?
1.减少hash碰撞 (2n ,16=24)
2.需要在效率和内存使用上做一个权衡。这个值既不能太小,也不能太大。
3.防止分配过小频繁扩容
4.防止分配过大浪费资源
4.HashMap为什么每次扩容都以2的整数次幂进行扩容?
因为Hashmap计算存储位置时,使用了(n - 1) & hash。只有当容量n为2的幂次方,n-1的二进制会全为1,位运算时可以充分散列,避免不必要的哈希冲突,所以扩容必须2倍就是为了维持容量始终为2的幂次方。
5.HashMap的扩容因子为什么是0.75?
当负载因子为1.0时,意味着只有当hashMap装满之后才会进行扩容,虽然空间利用率有大的提升,但是这就会导致大量的hash冲突,使得查询效率
本文深入探讨了Java HashMap的底层原理,包括扩容机制、初始容量选择、扩容因子设定、红黑树转换阈值以及线程不安全性等问题。详细分析了为何每次扩容以2的整数次幂进行,为什么扩容因子设为0.75,以及为什么在链表长度达到8时转为红黑树。此外,还讨论了HashMap与Hashtable、HashSet的异同,揭示了HashMap的高效性和潜在风险。
最低0.47元/天 解锁文章

600

被折叠的 条评论
为什么被折叠?



