Java集合面试题(三)

本文详细探讨了HashMap的线程安全性、哈希冲突解决方案、扩容机制、先插入再扩容策略,以及负载因子的作用和设置。还介绍了如何使用ConcurrentHashMap提高性能,并列举了五种删除元素的方法。

1、HashMap是线程安全吗

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

2、HashMap如何解决hash(哈希)冲突

hash冲突即多个对象的hashCode一致,当发生冲突时,它们会放到当前数组索引位置的链表中,在JDK 1.8+中,如果链表长度(>=8)并且数组长度(>=64)会转换成红黑树。

3、HashMap如何扩容

HashMap的扩容是由capacityloadFactorthreshold等参数值决定。

在数据很大的情况下,扩展时将会带来性能的损失。

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删除

具体实现例子请自行百度~

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值