Java Hashmap内部

San*_*San 3 java arrays hashmap

我对Java HashMap类几乎没有疑问.这是我的理解

 transient Entry[] table;
Run Code Online (Sandbox Code Playgroud)

表数组将根据值保存数据hashCode().我需要知道这个数组何时初始化.数组长度是基于我们在HashMap初始化期间定义的容量还是默认容量16,如果在调用构造函数时没有定义它?

hashcode如何缩放到数组索引?例如,如果哈希码具有巨大的值,它如何缩放到数组索引,如10,20?

我已经读过,当达到阈值时,将发生重新散列.例如,在默认情况下,当16是容量而0.75是负载因子时,则阈值为16*0.75=12.一旦添加了12个项目,将发生重新加载并且容量将增加.这是否意味着table数组大小增加了?

ent*_*erd 6

由于你的帖子有很多问题,我将列举你的问题作为我答案的一部分.另外,请注意我的答案是HashMap关于Java 1.8 b132的源代码.

  1. 问:我需要知道这个数组何时被初始化.
    答:table只有在数据首次输入地图时才会初始化数组(例如put()方法调用).它不会作为地图实例化的一部分本身发生,除非调用复制构造函数,或者将地图反序列化为对象.
  2. 问:数组长度是基于我们在HashMap初始化期间定义的容量还是默认容量16,如果在调用构造函数时没有定义它?
    答:正确,table数组的长度是基于传递给构造函数的初始容量.如果未指定初始容量且调用默认构造函数,则使用默认容量.
  3. 问:哈希码如何缩放到数组索引?
    答:对于执行此操作的实际代码本身,请参阅putVal()方法实现.基本上发生的是代码获取非常大的哈希值并bitwise-AND使用表的最后一个元素索引执行a .这有效地随机化了键/值对与table阵列的位置.例如,如果散列值为333(基数为2的101001101)且table数组大小为32(100000),则最后一个元素索引为31(11111).因此,所选择的指数将是11111 & 101001101 == 01101 == 13.
  4. 问:我已经读过,当达到阈值时,将发生重新散列....这是否意味着表数组大小增加了?
    答:或多或少,是的.当threshold超过时,表的大小.请注意,通过调整大小,table不会修改现有数组.而是table创建一个新阵列,其容量是第一个table阵列的两倍.有关详细信息,请参阅resize()方法的实现.