引言
最近在翻看《阿里巴巴开发手册-嵩山版》即最新版时,发现其修正了关于「HashMap关于1024个元素扩容的次数」 在先前的版本泰山版我们可以看到以下描述:

图片而最新版嵩山版则可以看到:

图片同时我们也可在嵩山版的版本历史中看到对以上变化的描述:

图片并且我在官网文档中也同样发现了采访视频对这一变化,主持人对孤尽老师提出了以下疑问:
主持人:
❝
有同学问,嵩山版修正了 HashMap 关于 1024 个元素扩容的次数?那么这个泰山版中是七次扩容,我感觉是正确的,为什么现在进行了修改?
❞
孤尽老师:
❝
大家可以看到嵩山版描述都改了,就没有讲「扩容」,讲叫「resize」的次数。因为 resize 的这个次数的话,我们在调 resize 的时候,就 put,如果你new了一个 HashMap 它并不会给你分配空间,第一次 put 的时候,它才会给你分配空间。所以就是说我们在第一次 put 的时候,也会调 resize。但是很多同学就会争议,说这个算不算扩容?那其实就是说我们在这个点上,其实为了,因为计算机我们大家都是搞计算机的,都希望用没有「二义性」的语言来表示。所以在嵩山版本里面进行了修改,然后我们改成了 resize 的方式来说明这到底是它的容量是如何变化的。因为扩容这个词的话,大家的理解是不一样的。这也是我们有一次大概在业界我们有一个打卡就是一个打卡测试题,这个题里面我们有一个选项。当时选的同学是两种答案,但是这两种答案都是有自己的道理。所以我们也是借鉴了这个看法,然后在这个嵩山版里面也写的更加明确了。就是叫 resize 的次数,不叫扩容的次数。
❞
以下是文档下载链接和采访视频地址。
https://developer.aliyun.com/topic/java20。
我们可以从孤尽老师的回答中提炼出主要发生的变化是:
- 扩容次数修改为「resize次数」 。主要的问题是每个人对「扩容」这个定义存在分歧。
- 扩容的主要分歧是在:没有给 HashMap 进行初始化的时候,第一次 put 的时候才会分配空间,也会调用 resize。那这操作个算不算扩容?即初始化容量这个操作算不算扩容?

图片那么我们先来看一下第一次 put 的时候调用 resize 这个操作是什么?
第一次put调用resize()
前面孤尽老师的回答中也强调了这个 put() 方法调用 resize() 方法是存在一个条件的:
「如果你new了一个HashMap它并不会给你分配空间。同时文档中也写了由于没有设置容量初始大小。」
❝
除了这个条件其实还有一个额外的条件,就是这是在 JDK1.8 之后 HashMap 才会有的操作。以下源码都来自 JDK1.8。
❞
要理解这句话我们首先要看下 HashMap 的源码,看下它的构造器方法。

图片存在四个构造方法
//参数:初始容量,负载因子
public HashMap(int initialCapacity, float loadFactor) { }
//参数:初始容量。调用上一个构造函数,默认的负载因子(0.75)
public HashMap(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); }
//参数:无参构造器。创建的HashMap具有默认的负载因子(0.75)
public HashMap() { this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted }
//参数:使用与指定Map相同的映射构造一个新的HashMap。创建的HashMap具有默认的负载因子(0.75)和足够在指定Map中保存映射的初始容量。
public HashMap(Map<? extends K, ? extends V> m) {
this.loadFactor = DEFAULT_LOAD_FACTOR;
putMapEntries(m, false);
}
也就是说当我们使用一个无参构造器创建 HashMap 的时候。
Map<String,String> map = new HashMap<>();
调用的就是上述构造方法的第三个方法,只会设置默认的负载因子为 0.75。就没有其他操作了。。
而当我们对这个 HashMap 进行 put() 操作的时候。
Map<String,String> map = new HashMap<>();
map.put("first","firstValue");
我们看一下源码,进行了什么操作?

图片public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
/**
* Implements Map.put and related methods.
*
* @param hash hash for key
* @param key the key
* @param value the value to put
* @param onlyIfAbsent if true, don't change existing value
* @param evict if false, the table is in creation mode.
* @return previous value, or null if none
*/
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null |" alt="为什么阿里巴巴修正了HashMap关于1024个元素扩容的次数?">