【这是我之前看到的好像一个比较经典的场景题,感觉也涉及比较多的知识点,之前学习记录后没往上发,所以也忘记是学习阅读了哪里的内容了】

如果我要存储100个数据,开多大的HashMap比较合适?

首先需要知道一些知识点:

HashMap会默认给我们初始化一个默认长度为16的数组。达到临界值就会扩容。其临界值的算式如下:

临界值(threshold) = 负载因子(loadFactor) * 容量(capacity)。

loadFactor 是装载因子,表示 HashMap 满的程度,默认值为 0.75,也就是说默认情况下,当 HashMap 中元素个数达到了容量的 3/4 的时候就会进行自动扩容。

那么为什么负载因子要设置成0.75呢,这个是经过了科学测试的。

设置得太小:导致HashMap空间利用率不高,扩容的频率也会更高,扩容的时候需要把数据重新计算哈希排列,这样会影响性能。

设置得太大:产生hash冲突的几率会很高,因为hash冲突的数据会放到同一个链表,这样会加长链表的长度,同样也会影响HashMap的性能。

HashMap扩容:

hashmap扩容分为两步:

  1. 扩容:创建一个新的Entry空数组,长度是原数组的2倍。
  2. ReHash:遍历原Entry数组,把所有的Entry重新Hash到新数组。
    为什么要重新Hash呢,不直接复制过去呢? 因为长度扩大以后,Hash的规则也随之改变。

Hash的公式---> index = HashCode(Key) & (Length - 1)

当然,也不可能一直扩容,总得有个限制,源码如下:换算即为1073741824

static final int MAXIMUM_CAPACITY = 1 << 30;

自定义HashMap的大小:

我们知道,我们在使用HashMap的时候是可以自定义其容量大小,比如new HashMap(10);而上面我们说过数组的大小为2的次幂,那么这个时候怎么处理的呢?

调用tableSizeFor()方法,即可得到大于输入参数且最近的2的整数次幂的数

由上述知识,我们可以知道,长度应该是2的倍数,。表面上看,大于100的最小的2的倍数是128,这应该是个比较合适的数,但是根据临界值计算128*0.75=96,得知开128仍然不能存储100个数,所以还是需要扩容,则应该取256.