当前位置: 首页 > article >正文

HashMap的寻址算法(源码分析)

建议先看完我这篇文章HashMap底层原理-CSDN博客

hashmap插入值的时候,是如何找到数组索引位置的呢?

        例如下图左边四个连续红点,是如何在插入的时候定位到了数组下标为3的位置?

 来看看put方法的源码,里面有个hash(key),这个就是定位数组位置的方法。

public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

我们进去看看

  static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

        h = key.hashCode()) ^ (h >>> 16),这一步就是我们想要的hash值。

put底层又对这个哈希值做了取模运算,下面看着是与运算,其实就相当于对数组长度取模。

  if ((p = tab[i = (n - 1) & hash]) == null)

        先通过key的hashCode方法获取第一次哈希值,再或上key右移16位,这是二次哈希,右移16位相当于除以2的16次方。得到的值再对数组长度取模,此时算出来的值对应数组下标。这就是HashMap的寻址算法,也叫扰动算法。

        这么做的目的就是让hash值更均匀,减少hash冲突,不信你可以自己生成随机数,让他用这个算法,统计数组上不同位置元素个数,你会发现基本上是均匀分布的。数据均匀分布的好处就是提高查找效率,不至于一堆数据全部集中在数组一个点,查找数据还得走很长的链表或者很高的红黑树,效率都不怎么样。

        

         而且与运算和取模效果一样是有前提的,数组长度必须是2的n次方,不然你就会看到下面的情况,两个算出来的答案不一样。

        提个小问题,你知道为什么上面算数组下标要用与运算而不直接用取余(模)?

        因为效率问题,与运算效率更高,计算机底层只有0和1,与运算更加快捷。
 


http://www.kler.cn/a/410545.html

相关文章:

  • Python人工智能项目报告
  • vue实现列表滑动下拉加载数据
  • 洛谷 B3635 硬币问题 C语言 记忆化搜索
  • uniapp+vue2重新进入小程序就清除缓存,设备需要重新扫码
  • TCP快速重传机制为啥出现重复ACK?
  • MTK主板_安卓主板方案_MTK联发科主板定制开发
  • 路由器中继与桥接
  • WPF中如何让Textbox显示为一条直线
  • Kali Linux语言设置成中文
  • 硬盘(HDD)与固态硬盘(SSD)详细解读
  • WSL安装不同版本ubuntu(已有ubuntu20.04,再装ubuntu18.04)
  • Linux(Ubuntu)升级openssh至9.6版本
  • PyTorch2
  • 树链剖分(重链剖分)
  • ES实用面试题
  • 什么是 C++ 中的类型别名和 using 声明? 如何使用类型别名和 using 声明?
  • 三维测量与建模笔记 - 点特征提取 - 4.5 SURF-FAST-ORB
  • Linux——进程调度与切换
  • 风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
  • 《Docker Registry(镜像仓库)详解》
  • vue实现列表滑动下拉加载数据
  • sql server 主从job对比差异
  • python画图|无坐标轴自由划线操作fig.add_artist(lines.Line2D()函数
  • 英伟达推出了全新的小型语言模型家族——Hymba 1.5B
  • 【开发小技巧11】用经典报表实现badge list效果,根据回显内容用颜色加以区分
  • 【SQL Server】华中农业大学空间数据库实验报告 实验八 存储过程