分散的列表(也称为哈希表)是一个数据结构,该数据结构是根据关键代码值直接访问的。搜索速度。此映射功能称为散射功能,记录记录的数组称为分布列表。
Hashmap是Java程序员用于钥匙值(键值)数据处理的最常见容器。当JDK1.7(Java Developmet套件)时,Hashmap采用阵列+链接表单来存储数据,JDK1.8 PailShashMap优化了存储结构并引入了红色黑树的数据结构,从而大大增强了Hashmap的访问性能!您是否介绍了红树和黑树?因为哈希姆普存在问题,即使负载因子和哈希算法设计合理,也无法避免链接列表中过度拉链的问题。如果在极端情况下发生严重的哈希冲突,它将严重影响hashmap的访问性能,Sohashmap在JDK1.8引入了红色和黑树,并使用红树和黑树的特征快速添加,删除和调查以优化优化hashmap的性能!
Java定义了数据结构中的映射(密钥值对)的接口Java.util.map。有四个接口,我们在开发中使用更频繁的实现类,即Hashmap
1hashmap
哈希姆普中的哈希算法分为三个步骤,第二步是使用16位参与操作的哈希值,以确保当数组的长度相对较小时,可以确保高和低和低和低位参与哈希行动,性能消耗太多。第三步是,当n是2个整数的力量时,哈希&(n-1)等同于对哈希值进行模具,并且钻头计算比模具的成型操作更有效;可以通过图标查看特定过程。
步骤1:通过key.hashcode()获取key的hashcode;
步骤2:通过(h = key.hashcode()) ^(h >>> 16),16-bit操作;
步骤3:通过(n -1)&哈希,获得计算的哈希值模具以获得节点的阵列。
步骤1:确定数组表[i]的键值是否为空/null,然后执行resize()扩展。
步骤2:根据键键计算哈希,以获取插入数组的索引i。如果直接插入了标签[i] == null,请执行第六步;如果标签[i]!= null,执行第三步。
步骤3:确定标签[i]的第一个元素是否等于插入元件密钥的hashcode&equals等于相等,并且相同的覆盖范围,否则第四步是执行。
步骤4:确定标签[i]是否是红色和黑色树节点treeNode,然后将节点插入红色和黑色树中,否则第五步将执行。
步骤5:遍历选项卡[i]确定链接列表是否大于8,大于8可以转换为红色和黑树(数组需要大于64),然后将节点插入红色和黑树中;如果在该过程的过程中存在HashCode&Equals,同样替换了。
步骤6:插入成功,并确定哈希图的大小是否超过阈值的值。
put(k键,v值)
计算Key的哈希值
putval(int hash,k键,v值,boolean hollyifabsent,布尔驱逐)
扩张
在JDK1.8中,当哈希图扩展发生时,我们可以通过源代码找到hashmap并未重新确定节点的位置通过新数组长度。新数组中的节点。当(e.hash&oldcap)== 0时,新数组中节点的位置与旧数组的位置一致;)= 0,新数组中节点的位置为J + OldCap,IS,原始位置加上旧数组的长度。
在这里提出了两个问题,并分析了问题,
问题1:为什么会这样实现?
问题2:之前具有相同哈希值的节点在数组的相同索引位置中随机分配给两个新的索引位置。这会导致获得(键)时无法获得的元素吗?
三个先决条件1.数组为16时hashmap的数组的默认大小,如果我们的设定值的初始值不是2的总体功率,则它将自动计算一个最接近初始化值2.的一个。可以查看源代码中的TableSizeFor()方法的总体功率的初始值。
2.扩展hashmap容量的方法是OldCap << 1,必须是原始扩展到原始的两倍。
3.哈希姆普计算数组索引(n -1)和哈希的方法
阵列的初始尺寸为16,容量扩展因子为0.75。依次插入三个节点。节点的关键是key1,key2和key3.need扩展
目前,下图(大小= 12)中所示的哈希图假设中的元素分布扩展了容量
扩展的算法是E.Hash&OldCap。计算后,发现键2的值为0。它保持在旧数组的中间和较低竞标位置。Key1和key3需要转移到J + OldCap的位置,即1 + 16 = 17降低竞标位置
扩展后的节点分布图
目前,我们查看根据密钥获得元素的守则
从上面的源代码中,我们可以非常清楚地看到它。在节点所在的数组中获得投标的方法为(n -1)&哈希,这与计算插入插入节点时计算数组的竞标相同。在key1,key2,key2,key3中准确地找到?原因是n的值变为原始的两倍,节点的哈希值不会更改。目前,计算出的节点处于数组位置,并且在扩展容量时我们执行的节点运动操作(可以或也可以扩展(也可以扩展)。;当我们获得key1,key2和键的索引时