HashMap,为什么要设置初始容量,容量设置为多大更好

我们日常经常定义hashMap,是这样的:

Map<String,String> map = new HashMap<>();

可是就是这样一句简单的代码,都可以优化,那就是给map设置初始容量大小。比如:

Map<String,String> map = new HashMap<>(4);

当用代码检查工具扫描时,也会提醒你设置初始容量

一、如果不设置初始大小,那默认大小是多大?

1、如果不设置初始容量,那么构造方法是这样的:

 即,所有Map相关属性全部用默认值

2、当put第一个元素时,因为map的Node<K,V>[] table为空,所以需要resize()

  3、接下来走resize方法,因为其他属性都为默认值,所以容量大小会设置为:DEFAULT_INITIAL_CAPACITY

 我们可以看到这个值默认为16 

 所以,这时的map的node数组,是一个容量为16的数组

二、如何扩容的

1、看一下put方法

 当元素个数>threshold时,会触发扩容。

扩多大呢?代码会走到这里:

 即:扩容到原容量的2倍。

 

回答标题的问题:为什么要设置初始容量?

  1、如果你的map只需要put几个元素,那么这样就会造成容量的浪费。

  2、如果你的map需要put成百上千个元素,那么这个map就会不断扩容(从16、32、64、128...),扩容需要创建新数组,并且rehash等操作,这样会导致一些性能的浪费。

  所以,如果在写代码时,如果能够预估map的容量,就可以尽量去设置他的容量大小,这样可以减少容量浪费减少扩容次数

3、初始容量设置为多大?

通过上面的内容可以看到,当元素个数超过总容量的0.75倍时,会触发扩容,此时容量为此前的2倍。

通过测试,也证实了如上的说法:

当元素为1时,扩容大小为2。

当元素为2时,扩容大小为4。

当元素为3时,扩容大小为4。

当元素为4时,扩容大小为8。

当元素为5时,扩容大小为8。

当元素为6时,扩容大小为8。

当元素为7时,扩容大小为16。(7 > 8 * 0.75)

。。。

所以如何设置一个初始容量,从而减小扩容次数呢?

设置容量的大小应该是:

1、预估元素个数,m(比如:5)

2、取离m最近的2的n次方的值:x(比如:8)。

3、如果大于 m>0.75x,则x=x*2

 

posted @   daibiao123  阅读(1236)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示