java map存放容量 java map容量上限_自定义


1. HashMap的容量与性能

HashMap的性能受到两个参数的影响:初始化容量和负载因子,下面来详细讲述这几个关键问题。

1.1 Initial Capacity与Load Factor

  • Initial Capacity:初始化容量,它表示HashMap底层的那个数组,也就是Entry数组有多长,这个值默认是16。
  • Load Factor:负载因子,它表示HashMap的负载程度,换句话说,它表示HashMap到底有多满了,是不是需要扩容了,这个值默认是0.75f。

初始化容量和负载因子的默认值是Java官方经过实践和优化得到的数据,可以适应大多数的场景。

当然也可以不使用其默认值,可以在构造的时候,自定义HashMap的容量和负载因子:


//单纯指定容量
Map<String,String> hashMapWithCapacity=new HashMap<>(64);
//自定义容量和负载因子
Map<String,String> hashMapWithCapacityAndLF=new HashMap<>(64, 0.9f);


一旦需要自定义容量和负载因子,我们需要搞清楚,他们到底是什么,用来干嘛,会对性能造成什么影响。

一句话:这两个数值会影响到HashMap的扩容,而扩容是一个对性能影响非常大的操作。

1.2 HashMap的扩容

1.2.1 扩容是什么

HashMap的扩容:HashMap被初始化之后,其容量是有限的(可以是默认,也可以是自定义的),当元素不断被插入,是HashMap达到一定的程度(负载因子决定),这个时候,HashMap就会扩容。

根据源码,使用公式表示,是否扩容由容量和负载因子的乘积决定!!!!


触发扩容的条件:
HashMap.Size   >=  Capacity * LoadFactor


  • HashMap.Size:当前HashMap的实际元素个数
  • Capacity:容量
  • LoadFactor:负载因子

如果在默认值的条件下:


HashMap.Size   =  16 * 0.75 = 12


也就是,默认的情况下,插入十二个元素的时候,就会触发扩容。

1.2.2 扩容的步骤

一旦HashMap的size超过了Capacity * LoadFactor乘积,就会触发扩容,那如何扩容呢?,需要经过两步:

  • resize:即:创建一个new Entry数组,长度是原来old Entry的2倍。
  • rehash:遍历old Entry数组,把里面的每一个元素取出来重新计算hash和index。为什么要重新计算呢?想一想之前的index计算公式:
index =  hash值 & (length - 1)


对,因为长度已经改了,所以index肯定会不一样,举个例子:

  • 当原数组长度为16时,Hash运算是和1111做与运算;
  • 新数组长度为32,Hash运算是和11111做与运算。

Hash结果显然不同。

1.3 容量与性能(常见问题)

综上所述,不同的容量和负载因子的设置,会导致hashmap的扩容频率不一致。所以:

  • Initial Capacity设置得低,存储空间少,但是增加了rehash的频率。所以如果能够预期到会存储比较多的数据,那么这个值应该设置高一点
  • Initial Capacity设置得高,存储空间多,rehash频率少。但是会增加迭代的成本。

所以总结一个场景

  • Initial Capacity设置高:大量存储,少量迭代
  • Initial Capacity设置低:数据少,迭代频繁

常见问题:

  • 如何扩容的
  • 初始化容量是多少,如何设置,有什么应用场景
  • 负载因子的作用是什么

欢迎大家一起交流!