1、HashMap是线程安全吗
HashMap是线程不安全,它所有方法都是非syncrhonized修饰,下图为源码注释:

2、HashMap如何解决hash(哈希)冲突
hash冲突即多个对象的hashCode一致,当发生冲突时,它们会放到当前数组索引位置的链表中,在JDK 1.8+中,如果链表长度(>=8)并且数组长度(>=64)会转换成红黑树。
3、HashMap如何扩容
HashMap的扩容是由capacity、loadFactor、threshold等参数值决定。
在数据很大的情况下,扩展时将会带来性能的损失。
1)capacity:指tab数组容量大小,默认容量为16,可以自定义容量,最大容量限制是1<<30。
2)loadFactor:指负载因子,默认值为0.75,用来计算扩容阈值threshold,决定tab数组需要扩容的时机。
3)threshold:指扩容阈值,默认值为12,当tab数组实际元素的长度超过扩容阈值时,tab才会扩容。
扩容机制:
1)正常扩容:如果采用默认容量,当数组实际大小>12时就会扩容,下图为部分源码:
2)hash冲突扩容:当链表的长度达到8,数组的默认容量为16,在数组长度<64之前都会扩容,扩容后tab数组的长度会变成原来的2倍,如下为部分源码:

4、HashMap是先插入元素还是先扩容
HashMap是先插入元素,然后再扩容。
为什么要先插入元素再扩容?
HashMap插入元素逻辑不一定是新增元素,有可能是更新已有的元素值。而先扩容的逻辑是每次插入元素之前都要先判断是否需要扩容,因此先插入少做了一步判断,一定程度上可以提升性能,设计上也相对合理。
5、HashMap容量限制
HashMap最大容量限制为10亿+:1073741824

6、HashMap如何实现同步
1)使用Collections的synchronizedMap()方法。
2)使用ConcurrentHashMap。
3)对操作Map的方法实现一个对象锁。
推荐使用ConcurrentHashMap,它不需要锁定整个对象,性能更好。
7、简述HashMap的负载因子
HashMap的负载因子指的是loadFactor(默认值为0.75)参数,负载因子用来计算扩容阈值threshold,决定HashMap数组需要扩容的时机,在时间和空间成本之间较为平衡。

8、HashMap的负载因子为什么是0.75
0.75是经过一系列比对之后,在平衡内存和性能之间取得比较好的权衡。
1)如果负载因子过高(1.0),表示容量满了才扩容,那么填满的元素就会越多,空间利用率也就越高,但hash冲突的几率也会加大。
2)如果负载因子过低(0.5),表示容量达到一半就扩容,那么填满的元素就会越少,空间利用率也就越低,但hash冲突的几率也会减少。

源码翻译过来的意思就是,HashMap的负载因子(loadFactor)默认值为0.75,意味着哈希表容量达到75%时会触发扩容操作。这是在时间和空间成本之间提供了一个很好的权衡,这样可以确保哈希表不会过早地扩容而浪费内存,同时在大部分情况下也不会过度填充,导致性能下降。
9、如何合理设置HashMap的负载因子
设置负载因子需要根据具体应用的需求来平衡内存和性能。
1)如果注重性能,可以降低负载因子,但会消耗更多内存。
2)如果注重内存,可以增加负载因子,但会降低性能。
10、简述5个根据value删除HashMap元素的方法
1)使用for循环删除
2)使用forEach循环删除
3)使用Iterator迭代器删除
4)使用removeIf删除
5)使用Stream删除
具体实现例子请自行百度~
本文详细探讨了HashMap的线程安全性、哈希冲突解决方案、扩容机制、先插入再扩容策略,以及负载因子的作用和设置。还介绍了如何使用ConcurrentHashMap提高性能,并列举了五种删除元素的方法。
1403

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



